diff --git a/.gitattributes b/.gitattributes index 2cee0e56b..de87e69fe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,16 +9,16 @@ # Fortran files *.f text diff=fortran *.for text diff=fortran -*.f90 text diff=fortran -*.F90 text diff=fortran -*.f95 text diff=fortran -*.f03 text diff=fortran -*.x90 text diff=fortran -*.X90 text diff=fortran -*.t90 text diff=fortran -*.T90 text diff=fortran -*.pf text diff=fortran -*.PF text diff=fortran +*.f90 text diff=fortran-free-form +*.F90 text diff=fortran-free-form +*.f95 text diff=fortran-free-form +*.f03 text diff=fortran-free-form +*.x90 text diff=fortran-free-form +*.X90 text diff=fortran-free-form +*.t90 text diff=fortran-free-form +*.T90 text diff=fortran-free-form +*.pf text diff=fortran-free-form +*.PF text diff=fortran-free-form # Enable syntax highlighting for files with `.pf` extensions. # diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0509682e8..979887d62 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,80 @@ -**/jules_interface/rose-meta @maggiehendry -**/jedi_lfric* @MetOffice/r2o -**/linear* @MetOffice/r2o +# This CODEOWNERS file includes a primary codeowner and a deputy for each section. +# Codeowners who are not in a comment will be automatically notified of changes +# to the listed files. All codeowners listed are valid points of contact +# for discussing changes and seeking approval for work. + +# Applications +**/adjoint_tests @DrTVockerodtMO # @mo-joshuacolclough +**/gravity_wave @thomasmelvin # @cjohnson-pi +**/gungho_model @thomasmelvin # @BShipway +**/jedi_lfric_tests @ss421 @matthewrmshin @MetOffice/r2o-systems +**/jules @iboutle # @MetOfficessdtesam +**/lfric2lfric @mo-lottieturner # @mike-hobson +**/lfricinputs @mo-lottieturner # @mike-hobson +**/lfric_atm @iboutle # @BShipway +**/lfric_coupled @HengistPodd # @BShipway +**/lfricinputs @mo-lottieturner # @mike-hobson +**/linear_model @cjohnson-pi @MetOffice/r2o-systems # @tommbendall # Also notifiy jedi team about linear changes. +**/name_transport @jameskent-metoffice # @tommbendall +**/ngarch @christophermaynard # @jcsmeto +**/shallow_water @jameskent-metoffice # @atb1995 +**/solver @christophermaynard # @thomasmelvin +**/transport @tommbendall # @jameskent-metoffice + +# Science +**/adjoint @DrTVockerodtMO # @mo-joshuacolclough +**/linear @cjohnson-pi @MetOffice/r2o-systems # @tommbendall # Also notifiy jedi team about linear changes. +science/shared/source/constants/ @iboutle # @BShipway + +**/gungho @thomasmelvin # @iboutle +science/gungho/**/configuration/ @jameskent-metoffice # @thomasmelvin +science/gungho/**/core_dynamics/ @jameskent-metoffice # @thomasmelvin +science/gungho/**/diagnostics/ @atb1995 # @iboutle +science/gungho/**/diffusion/ @iboutle # @tommbendall +science/gungho/**/driver/ @MetOffice/core-capability-development +science/gungho/**/external_forcing/ @iboutle # @tommbendall +science/gungho/**/initialisation/ @mo-cjsmith # @thomasmelvin +science/gungho/**/limited_area/ @cjohnson-pi # @thomasmelvin +science/gungho/**/orography/ @atb1995 # @tommbendall +science/gungho/**/physics/ @iboutle # @tommbendall +science/gungho/**/psy/ @thomasmelvin # @tommbendall +science/gungho/**/runtime_constants/ @tommbendall # @atb1995 +science/gungho/**/solver/ @thomasmelvin # @tommbendall +science/gungho/**/timestepping/ @thomasmelvin # @jameskent-metoffice +science/gungho/**/transport/ @tommbendall # @jameskent-metoffice + +**/physics_schemes @iboutle # @MetOffice/ssdteam +science/physics_schemes/**/boundary_layer @Adrian-Lock # @P-Burns +science/physics_schemes/**/convection @MichaelWhitall +science/physics_schemes/**/convection/comorph @MichaelWhitall +science/physics_schemes/**/large_scale_cloud @paul-barrett # @CyrilMorcrette +science/physics_schemes/**/large_scale_precipitation @paulfield2024 # @paul-barrett +science/physics_schemes/**/radiation_control @mo-jmanners # @Petzi1 +science/physics_schemes/**/stochastic_physics @wjtmo # @annemccabe + +# Interfaces +**/coupled_interface @mike-hobson # @harry-shepherd +**/jedi_lfric_interface @ss421 @matthewrmshin @MetOffice/r2o-systems +**/jules_interface @iboutle # @MetOfficessdteam +**/jules_interface/rose-meta @maggiehendry +**/physics_schemes_interface @iboutle # @MetOfficessdteam +**/socrates_interface @mo-jmanners # @Petzi1 + +# System Components +rose-stem/templates/ @james-bruten-mo # @jennyhickson +rose-stem/lib/ @james-bruten-mo # @jennyhickson +rose-stem/bin/ @james-bruten-mo # @jennyhickson +rose-stem/site/meto/common/ @james-bruten-mo # @jennyhickson +rose-stem/site/meto/macros/ @james-bruten-mo # @jennyhickson +rose-stem/apps # Mostly updated by macros, no codeowner +**/versions.py @james-bruten-mo # @jennyhickson +build/ @MetOffice/ssdteam @hiker +**/*Makefile @MatthewHambley @hiker +**/*.mk @MatthewHambley @hiker +**/optimisation @christophermaynard # HPC Optimisation Team + +# Other areas +documentation # @MetOffice/ssdteam +.github/ @MetOffice/ssdteam +LICENSE @yaswant +README.md @MetOffice/ssdteam diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index d186d921a..d9804a62b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -6,15 +6,8 @@ body: - type: markdown attributes: value: | - Thanks for taking the time to fill out this bug report! - - type: input - id: contact - attributes: - label: Contact Details - description: How can we get in touch with you if we need more info? - placeholder: e.g. email@example.com @octocat - validations: - required: false + Thanks for taking the time to fill out this bug report! _If you are planning + to work on this issue, then please assign yourself to it._ - type: dropdown id: version attributes: @@ -24,7 +17,7 @@ body: - main default: 0 validations: - required: true + required: true - type: input id: linked-issues attributes: diff --git a/.github/ISSUE_TEMPLATE/custom_issue.yml b/.github/ISSUE_TEMPLATE/custom_issue.yml index 2feebab5e..a7efac109 100644 --- a/.github/ISSUE_TEMPLATE/custom_issue.yml +++ b/.github/ISSUE_TEMPLATE/custom_issue.yml @@ -6,15 +6,8 @@ body: - type: markdown attributes: value: | - Thanks for taking the time to help improve LFRic Apps. - - type: input - id: contact - attributes: - label: Contact Details - description: How can we get in touch with you if we need more info? - placeholder: e.g. email@example.com @octocat - validations: - required: false + Thanks for taking the time to help improve LFRic Apps. _If you are planning + to work on this issue, then please assign yourself to it._ - type: input id: linked-issues attributes: diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml index 9b3011e84..b7f28e622 100644 --- a/.github/ISSUE_TEMPLATE/documentation.yml +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -1,20 +1,13 @@ name: Documentation Issue -description: Report an issue with the LFRic Apps documentation or suggest an improvement. +description: Report an issue with the LFRic Apps documentation or suggest an improvement. labels: ["documentation"] type: task body: - type: markdown attributes: value: | - Thanks for taking the time to help improve the LFRic Apps documentation. - - type: input - id: contact - attributes: - label: Contact Details - description: How can we get in touch with you if we need more info? - placeholder: e.g. email@example.com @octocat - validations: - required: false + Thanks for taking the time to help improve the LFRic Apps documentation. + _If you are planning to work on this issue, then please assign yourself to it._ - type: input id: linked-issues attributes: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b7e5f2a21..240f53879 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,6 @@ # PR Summary -Sci/Tech Reviewer: +Sci/Tech Reviewer: Code Reviewer: @@ -22,26 +22,18 @@ Code Reviewer: ## Code Quality Checklist -(_Some checks are automatically carried out via the CI pipeline_) - - [ ] I have performed a self-review of my own code -- [ ] My code follows the project's style guidelines - [style guidelines](https://metoffice.github.io/lfric_core/how_to_contribute/index.html#how-to-contribute-index) -- [ ] Comments have been included that aid undertanding and enhance the - readability of the code +- [ ] My code follows the project's [style guidelines](https://metoffice.github.io/lfric_core/how_to_contribute/index.html#how-to-contribute-index) +- [ ] Comments have been included that aid understanding and enhance the readability of the code - [ ] My changes generate no new warnings +- [ ] All automated checks in the CI pipeline have completed successfully ## Testing - [ ] I have tested this change locally, using the LFRic Apps rose-stem suite -- [ ] If any tests fail (rose-stem or CI) the reason is understood and - acceptable (eg. kgo changes) -- [ ] I have added tests to cover new functionality as appropriate (eg. system - tests, unit tests, etc.) -- [ ] Any new tests have been assigned an appropriate amount of compute resource - and have tests been allocated to an appropriate testing group (i.e. the - developer tests are for jobs which use a small amount of compute resource - and complete in a matter of minutes) +- [ ] If any tests fail (rose-stem or CI) the reason is understood and acceptable (e.g. kgo changes) +- [ ] I have added tests to cover new functionality as appropriate (e.g. system tests, unit tests, etc.) +- [ ] Any new tests have been assigned an appropriate amount of compute resource and have been allocated to an appropriate testing group (i.e. the developer tests are for jobs which use a small amount of compute resource and complete in a matter of minutes) @@ -57,30 +49,21 @@ Code Reviewer: ## Performance Impact -- [ ] Performance of the code has been considered and, if applicable, suitable - performance measurements have been conducted +- [ ] Performance of the code has been considered and, if applicable, suitable performance measurements have been conducted ## AI Assistance and Attribution -- [ ] Some of the content of this change has been produced with the assistance - of _Generative AI tool name_ (e.g., Met Office Github Copilot Enterprise, - Github Copilot Personal, ChatGPT GPT-4, etc) and I have followed the - [Simulation Systems AI policy](https://metoffice.github.io/simulation-systems/FurtherDetails/ai.html) - (including attribution labels) +- [ ] Some of the content of this change has been produced with the assistance of _Generative AI tool name_ (e.g., Met Office Github Copilot Enterprise, Github Copilot Personal, ChatGPT GPT-4, etc) and I have followed the [Simulation Systems AI policy](https://metoffice.github.io/simulation-systems/FurtherDetails/ai.html) (including attribution labels) ## Documentation -- [ ] Where appropriate I have updated documentation related to this change and - confirmed that it builds correctly +- [ ] Where appropriate I have updated documentation related to this change and confirmed that it builds correctly ## PSyclone Approval -- [ ] If you have edited any psyclone related code (eg. PsyKAl-lite, Kernal - inteface, optimisation scripts, LFRic data structure code) then please - contact the - [tooscollabdevteam@metoffice.gov.uk](tooscollabdevteam@metoffice.gov.uk) +- [ ] If you have edited any PSyclone-related code (e.g. PSyKAl-lite, Kernel interface, optimisation scripts, LFRic data structure code) then please contact the [TCD Team](mailto:ToolsCollabDevTeam@metoffice.gov.uk) # Sci/Tech Review @@ -92,7 +75,7 @@ Code Reviewer: - [ ] Documentation is sufficient (do documentation papers need updating) - [ ] Sufficient testing has been completed -_Please alert the code reviewer via a tag when you have approved the SR_ +(_Please alert the code reviewer via a tag when you have approved the SR_) # Code Review diff --git a/.github/workflows/block-stable-base.yaml b/.github/workflows/block-stable-base.yaml new file mode 100644 index 000000000..e7b39d2e6 --- /dev/null +++ b/.github/workflows/block-stable-base.yaml @@ -0,0 +1,25 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + +# Block merges to the stable branch via pull requests + +name: Block PR to Stable + +on: + pull_request: + types: [opened, reopened, synchronize] + branches: + - stable + +jobs: + block-merge: + runs-on: ubuntu-latest + steps: + - name: Block merge to stable branch + run: | + echo "::error::Direct merges to the stable branch are not allowed." + echo "::error::Please target a different branch for your pull request." + exit 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci_docs.yml similarity index 81% rename from .github/workflows/ci.yml rename to .github/workflows/ci_docs.yml index 381f55787..ba2bfcba0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci_docs.yml @@ -4,13 +4,16 @@ # under which the code may be used. # ------------------------------------------------------------------------------ -name: ci -run-name: CI +name: Documentation +run-name: Docs Build and Deploy - ${{ github.ref_name }} on: push: branches: - main + paths: + - 'documentation/**' + - '.github/workflows/**' concurrency: group: ${{ github.workflow }}-${{github.ref}} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr_docs.yml similarity index 77% rename from .github/workflows/pr.yml rename to .github/workflows/pr_docs.yml index 72693292e..eb34c21f1 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr_docs.yml @@ -4,12 +4,15 @@ # under which the code may be used. # ------------------------------------------------------------------------------ -name: pr -run-name: Pull Request ${{github.event.pull_request.number}} +name: Docs Build for Pull Requests +run-name: Docs build PR${{github.event.pull_request.number}} on: pull_request: branches: - main + paths: + - 'documentation/**' + - '.github/workflows/**' concurrency: group: pr-${{github.ref}}-${{github.event.pull_request.number || github.run_number}} diff --git a/.github/workflows/ru_deploy-docs.yml b/.github/workflows/ru_deploy-docs.yml index 2867b69d7..b38957771 100644 --- a/.github/workflows/ru_deploy-docs.yml +++ b/.github/workflows/ru_deploy-docs.yml @@ -11,6 +11,7 @@ on: jobs: deploy: + if: ${{ github.repository == 'MetOffice/lfric_apps' }} environment: name: github-pages permissions: diff --git a/.github/workflows/track-review-project.yaml b/.github/workflows/track-review-project.yaml new file mode 100644 index 000000000..639477cd2 --- /dev/null +++ b/.github/workflows/track-review-project.yaml @@ -0,0 +1,17 @@ +name: Track Review Project + +on: + workflow_run: + workflows: [Trigger Review Project] + types: + - completed + +permissions: + actions: read + contents: read + pull-requests: write + +jobs: + track_review_project: + uses: MetOffice/growss/.github/workflows/track-review-project.yaml@main + secrets: inherit diff --git a/.github/workflows/trigger-project-workflow.yaml b/.github/workflows/trigger-project-workflow.yaml new file mode 100644 index 000000000..ccb7a55b0 --- /dev/null +++ b/.github/workflows/trigger-project-workflow.yaml @@ -0,0 +1,17 @@ +name: Trigger Review Project + +on: + pull_request_target: + types: ["opened", "synchronize", "reopened", "edited", "review_requested", "review_request_removed", "closed"] + pull_request_review: + pull_request_review_comment: + +permissions: + actions: read + contents: read + pull-requests: write + +jobs: + trigger_project_workflow: + uses: MetOffice/growss/.github/workflows/trigger-project-workflow.yaml@main + secrets: inherit diff --git a/.gitignore b/.gitignore index 31cbc46f8..c0c4638cc 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,15 @@ __pycache__ # LFRic CL Builds applications/**/bin +applications/**/documents applications/**/working +applications/**/test applications/**/example*/ science/**/bin +science/**/documents science/**/working +science/**/test +interfaces/**/bin +interfaces/**/documents +interfaces/**/working +interfaces/**/test diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d0f7ae14d..00c6e6edb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,6 +1,37 @@ # Contributors - -| GitHub user | Real Name | Affiliation | Date | -| ----------- | --------- | ----------- | ---- | -| james-bruten-mo | James Bruten | Met Office | 2025-12-09 | -| jennyhickson | Jenny Hickson | Met Office | 2025-12-10 | +| GitHub user | Real Name | Affiliation | Date | +| ------------------- | ------------------ | -------------------------------- | ---------- | +| james-bruten-mo | James Bruten | Met Office | 2025-12-09 | +| jedbakerMO | Jed Baker | Met Office | 2025-12-29 | +| jennyhickson | Jenny Hickson | Met Office | 2025-12-10 | +| mike-hobson | Mike Hobson | Met Office | 2025-12-17 | +| mo-marqh | mark Hedley | Met Office | 2025-12-11 | +| mo-rickywong | Ricky Wong | Met Office | 2026-24-02 | +| yaswant | Yaswant Pradhan | Met Office | 2025-12-16 | +| oakleybrunt | Oakley Brunt | Met Office | 2025-12-19 | +| harry-shepherd | Harry Shepherd | Met Office | 2026-01-08 | +| DrTVockerodtMO | Terence Vockerodt | Met Office | 2026-01-08 | +| ricky-lv426 | Ricky Olivier | University of Exeter | 2026-01-12 | +| MetBenjaminWent | Benjamin Went | Met Office | 2026-01-15 | +| timgraham-Met | Tim Graham | Met Office | 2026-01-15 | +| mcdalvi | Mohit Dalvi | Met Office | 2026-01-15 | +| mo-alistairp | Alistair Pirrie | Met Office | 2026-01-19 | +| jasonjunweilyu | Junwei (Jason) Lyu | Bureau of Meteorology, Australia | 2025-12-17 | +| EdHone | Ed Hone | Met Office | 2026-01-26 | +| tom-j-h | Tom Hill | Met Office | 2026-01-27 | +| alanjhewitt | Alan J Hewitt | Met Office | 2026-01-28 | +| mo-lottieturner | Lottie Turner | Met Office | 2026-01-27 | +| andrewcoughtrie | Andrew Coughtrie | Met Office | 2026-01-28 | +| tommbendall | Thomas Bendall | Met Office | 2026-01-13 | +| mo-jmanners | James Manners | Met Office | 2026-01-14 | +| maggiehendry | Maggie Hendry | Met Office | 2026-01-29 | +| stevemullerworth | Steve Mullerworth | Met Office | 2026-01-28 | +| jameskent-metoffice | James Kent | Met Office | 2026-01-21 | +| cjohnson-pi | Christine Johnson | Met Office | 2026-01-19 | +| t00sa | Sam Clarke-Green | Met Office | 2026-01-20 | +| ukmo-juan-castillo | Juan M. Castillo | Met Office | 2026-01-23 | +| Adrian-Lock | Adrian Lock | Met Office | 2026-01-09 | +| thomasmelvin | Thomas Melvin | Met Office | 2026-01-15 | +| tinyendian | Wolfgang Hayek | Earth Sciences New Zealand | 2026-02-02 | +| DanStoneMO | Daniel Stone | Met Office | 2026-02-26 | +| ericaneininger | Erica Neininger | Met Office | 2026-03-02 | \ No newline at end of file diff --git a/CodeOwners.txt b/CodeOwners.txt deleted file mode 100644 index 36b0e9873..000000000 --- a/CodeOwners.txt +++ /dev/null @@ -1,54 +0,0 @@ -= Code Owners = - -This file lists ownership of the major components in the LFRic Apps codebase. - -* Ownership is not a commitment for the individual to undertake all work - requested or all reviewing for the owned section. -* Any planned changes to a section should be discussed with the code owner to - ensure all plans are appropriate. -* Code owners should be given the option to be a science/technical reviewer - for any code that alters their sections. - -Contact details for code owners: https://code.metoffice.gov.uk/trac/home/wiki/UserList - -# Start of script readable lines - -= System Components = -{{{ -Area First Contact Second Contact Team -rose-stem jamesbruten jenniferhickson simulation_systems_and_deployment -build umsysteam@metoffice.gov.uk -- simulation_systems_and_deployment -Makefiles matthewhambley -- core_capability_development -}}} - -= Applications = -{{{ -Area First Contact Second Contact Team -adjoint_tests terencevockerodt joshuacolclough data_assimilation -gravity_wave thomasmelvin christinejohnson dynamics_research -gungho_model thomasmelvin benshipway dynamics_research -jedi_lfric_tests stevensandbach davidsimonin data_assimilation -lfric_atm ianboutle benshipway dynamics_research -lfric_coupled richardhill benshipway global_coupled_model_development -lfricinputs charlotteturner mikehobson core_capability_development -linear_model christinejohnson thomasbendall dynamics_research -name_transport jameskent thomasbendall dynamics_research -ngarch christophermaynard jamescunningham-smith ng-arch -shallow_water jameskent alexbrown dynamics_research -solver christophermaynard thomasmelvin ng-opt -transport thomasbendall jameskent dynamics_research -}}} - -= Science = -{{{ -Area First Contact Second Contact Team -adjoint terencevockerodt joshuacolclough data_assimilation -constants ianboutle benshipway dynamics_research -coupled_interface mikehobson jeanrioual -- -gungho thomasmelvin benshipway dynamics_research -jedi_lfric_interface stevensandbach davidsimonin data_assimilation -jules_interface ianboutle richardgilham atmospheric_processes_and_parametrizations -linear christinejohnson thomasbendall dynamics_research -socrates_interface jamesmanners stephanhavemann radiation -physics_schemes_interface ianboutle https://code.metoffice.gov.uk/trac/um/browser/main/trunk/CodeOwners.txt simulation_systems_and_deployment -}}} diff --git a/README.md b/README.md index e2d180047..1b0ff9fe1 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,38 @@ # LFRic Apps -[![ci](https://github.com/MetOffice/lfric_apps/actions/workflows/ci.yml/badge.svg)](https://github.com/MetOffice/lfric_apps/actions/workflows/ci.yml) +Welcome to LFRic Apps! This repository is home to the LFRic-based science applications and libraries such as -lfric_atm and the GungHo dynamical core. +the Momentum® Atmosphere model application and the GungHo dynamical core. LFRic applications are based on the infrastructure developed in the [LFRic Core](https://github.com/MetOffice/lfric_core) repository. +| | | +|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|:repeat: CI| [![Documentation](https://github.com/MetOffice/lfric_apps/actions/workflows/ci_docs.yml/badge.svg)](https://github.com/MetOffice/lfric_apps/actions/workflows/ci_docs.yml) | +|:speech_balloon: Community| [![Static Badge](https://img.shields.io/badge/GitHub-discussions-gold)](https://github.com/MetOffice/simulation-systems/discussions/categories/lfric) | +|:package: Repo | [![GitHub License](https://img.shields.io/github/license/metoffice/lfric_apps)](https://github.com/MetOffice/lfric_apps?tab=BSD-3-Clause-1-ov-file#readme) [![GitHub Release](https://img.shields.io/github/v/release/metoffice/lfric_apps?color=purple)](https://github.com/MetOffice/lfric_apps/releases) ![GitHub commits since latest release (branch)](https://img.shields.io/github/commits-since/metoffice/lfric_apps/latest/main) | +| | | + +## Getting Started + In development documentation for LFRic Apps is available at: [https://metoffice.github.io/lfric_apps](https://metoffice.github.io/lfric_apps) -## Contributing Guidelines +The LFRic Apps release schedule and deadlines can be viewed in the [milestones](https://github.com/metoffice/lfric_apps/milestones). + +Example standalone scientific suites for use with Met Office systems are +available at: -Welcome! +* [u-dn674 - MetOffice Azure SPICE](https://code.metoffice.gov.uk/trac/roses-u/browser/d/n/6/7/4/trunk) +* [u-dn704 - MetOffice EX HPC](https://code.metoffice.gov.uk/trac/roses-u/browser/d/n/7/0/4/trunk) + +These both run a low resolution LFRic Atm NWP GAL9 job and are setup to run +using git sources. Advice on switching a suite from using fcm to git sources is +available in the README.md in each. + +## Contributing Guidelines The following links are here to help set clear expectations for everyone contributing to this project. By working together under a shared understanding, diff --git a/applications/adjoint_tests/example/C12.nml b/applications/adjoint_tests/example/C12_MG.nml similarity index 91% rename from applications/adjoint_tests/example/C12.nml rename to applications/adjoint_tests/example/C12_MG.nml index d609be41c..048f08021 100644 --- a/applications/adjoint_tests/example/C12.nml +++ b/applications/adjoint_tests/example/C12_MG.nml @@ -25,11 +25,12 @@ ! respectively !=================================================================== &mesh - mesh_file_prefix = 'mesh_C12' + mesh_file_prefix = 'mesh_C12_MG' geometry = 'spherical' topology = 'periodic' - n_meshes = 1 - mesh_names = 'C12' + n_meshes = 3 + mesh_names = 'dynamics','multigrid_l1','multigrid_l2' + mesh_maps = 'dynamics:multigrid_l1','multigrid_l1:multigrid_l2' partition_mesh = .false. coord_sys = 'll' rotate_mesh = .false. diff --git a/applications/adjoint_tests/example/configuration.nml b/applications/adjoint_tests/example/configuration.nml index 84ce2a779..6061f8833 100644 --- a/applications/adjoint_tests/example/configuration.nml +++ b/applications/adjoint_tests/example/configuration.nml @@ -1,22 +1,42 @@ &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., / §ion_choice +aerosol='none', +boundary_layer='none', +chemistry='none', +cloud='none', dynamics='gungho', external_forcing=.false., iau=.false., +iau_sst=.false., iau_surf=.false., +methane_oxidation=.false., +orographic_drag='none', +radiation='none', +spectral_gwd='none', +stochastic_physics='none', +surface='none', +/ +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., / &damping_layer dl_base=40000.0, @@ -27,29 +47,32 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', -vertical_sorting=.false. +vertical_sorting=.false., / &energy_correction encorr_usage='none', integral_method='fd', / &extrusion -domain_height=10000.0, -method='uniform', -number_of_layers=5, +domain_height=80000.0, +method='um_L70_50t_20s_80km', +number_of_layers=70, planet_radius=6371229.0, -stretching_method='linear', +stretching_height=17507.0, +stretching_method='smooth', / &files ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='diagGungho', +ls_directory='/data/users/lfricadmin/data/tangent-linear/PullRequest182' +ls_filename='final_ls_with_land', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', +start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +start_dump_filename='final_pert', / &finite_element cellshape='quadrilateral', @@ -65,85 +88,99 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., p2theta_vert=.true., rotating=.true., -theta_moist_source=.false. shallow=.true., si_momentum_equation=.false., +theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., gcrk=18, -method='bicgstab', -monitor_convergence=.true., +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', +preconditioner='multigrid', si_pressure_a_tol=0, si_pressure_maximum_iterations=400, si_pressure_tolerance=1.0e-15, / +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau +/ &idealised -f_lon_deg=0, -perturb_init=.false. -test='gravity_wave', +f_lon_deg=0.0, +perturb_init=.false., +test='none', / &ideal_surface -canopy_height=0, -leaf_area_index=0, -n_snow_layers=0, -snow_depth=0, -snow_layer_ice_mass=0, -snow_layer_temp=0, -snow_layer_thickness=0, -soil_moisture=0, -soil_temperature=0, -surf_tile_fracs=0, -surf_tile_temps=0, -tile_snow_mass=0, +canopy_height=19.01,16.38,0.79,1.26,1.0, +leaf_area_index=5.0,4.0,1.5,1.5,1.5, +n_snow_layers=11*0, +snow_depth=11*0.0, +snow_layer_ice_mass=27*0.0, +snow_layer_temp=27*273.0, +snow_layer_thickness=27*0.0, +soil_moisture=15.86,98.861,274.35,862.27, +soil_temperature=284.508,286.537,289.512,293.066, +surf_tile_fracs=9*0.0,1.0,0.0, +surf_tile_temps=9*295.0,300.0,265.0, +tile_snow_mass=11*0.0, / &initialization ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., -init_option='analytic', +coarse_ozone_ancil=.false., +init_option='fd_start_dump', lbc_option='none', -ls_option='analytic', +ls_option='file', model_eos_height=100, n_orog_smooth=0, -read_w2h_wind=.false., +read_w2h_wind=.true., +sea_ice_source='ancillary', +snow_source='start_dump', w0_orography_mapping=.false., zero_w2v_wind=.false., / &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, z2=0.0, / &initial_pressure -method='sampled', +method='balanced', surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -152,39 +189,59 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='solid_body_rotation', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.5, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., -diagnostic_frequency=1, +diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., timer_output_path='timer.txt', use_xios_io=.true., write_conservation_diag=.false., -write_diag=.false., +write_diag=.true., write_dump=.false., write_fluxes=.false., write_minmax_tseries=.false., / &linear -pert_option='analytic', +fixed_ls=.true., l_stabilise_bl=.false., +ls_read_w2h=.false., +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', +transport_efficiency=.true., +/ +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, / &logging -run_log_level='info', +log_to_rank_zero_only=.false., +run_log_level='debug', / &mixed_solver eliminate_variables='discrete', @@ -194,8 +251,8 @@ guess_np1=.false., mixed_solver_a_tol=1.0e-21, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=10, +reference_reset_time=1800, +si_maximum_iterations=100, si_method='block_gcr', si_preconditioner='pressure', si_tolerance=1.0e-21, @@ -207,6 +264,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -214,12 +279,23 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +bl_segment=0, +configure_segments=.true., +conv_gr_segment=16, +gw_segment=0, +limit_drag_incs=.false., +ls_ppn_segment=0, +sample_physics_scalars=.true., +sample_physics_winds=.true., +sample_physics_winds_correction=.false., +ussp_segment=0, / &planet cp=1005.0, @@ -229,8 +305,41 @@ p_zero=100000.0, rd=287.05, scaling_factor=1.0, / +&radiative_gases +cfc113_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', +co_rad_opt='off', +cs_rad_opt='off', +h2_rad_opt='off', +h2o_rad_opt='prognostic', +hcfc22_rad_opt='off', +hcn_rad_opt='off', +he_rad_opt='off', +hfc134a_rad_opt='off', +k_rad_opt='off', +l_cts_fcg_rates=.false., +li_rad_opt='off', +n2_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', +na_rad_opt='off', +nh3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', +rb_rad_opt='off', +so2_rad_opt='off', +tio_rad_opt='off', +vo_rad_opt='off', +/ &solver -fail_on_non_converged=.false., gcrk=18, maximum_iterations=50, method='chebyshev', @@ -238,33 +347,36 @@ monitor_convergence=.false., preconditioner='diagonal', tolerance=1.0e-18, / +&specified_surface +/ &time calendar='timestep', calendar_origin='2016-01-01 15:00:00', calendar_start='2016-01-01 15:00:00', calendar_type='gregorian', -timestep_end='1', +timestep_end='12', timestep_start='1', / ×tepping alpha=0.55, -dt=3600.0, +dt=1800, +inner_iterations=1, method='semi_implicit', +outer_iterations=2, runge_kutta_method='forward_euler', spinup_alpha=.false., -spinup_period=0, -tau_u=0.55, tau_r=1.0, tau_t=1.0, -inner_iterations=2, -outer_iterations=2, +tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_tracer_equation=.false., +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -274,18 +386,19 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', @@ -293,27 +406,27 @@ min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', panel_edge_high_order=.true., -panel_edge_treatment='none' +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', -scheme=5*1, +scheme=5*3, si_outer_transport='none', slice_order='parabola', -special_edges_monotone=0,0,0,1,1 -splitting=5*1, +special_edges_monotone=5*1, +splitting=5*2, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test -number_gamma_values=0, -update_ls_frequency=0, +number_gamma_values=2, +update_ls_frequency=1, / diff --git a/applications/adjoint_tests/example/iodef.xml b/applications/adjoint_tests/example/iodef.xml index 8d0934e67..4e14df122 100644 --- a/applications/adjoint_tests/example/iodef.xml +++ b/applications/adjoint_tests/example/iodef.xml @@ -3,7 +3,6 @@ - @@ -11,10 +10,9 @@ - + - @@ -52,6 +50,11 @@ + + + + + @@ -68,26 +71,28 @@ - + + + - - - - - - + + + + + + @@ -102,14 +107,12 @@ - - - - - - - - + + + + + + @@ -123,6 +126,9 @@ + + + @@ -132,6 +138,8 @@ + + @@ -144,6 +152,15 @@ + + + + + + + + + processed__tot_col_uv_kinetic_energy + processed__tot_col_w_kinetic_energy @@ -169,41 +186,40 @@ + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - @@ -240,44 +256,24 @@ - + - + + - - - - - - + + - - - - - - - - - - - - - - - - - @@ -285,72 +281,54 @@ - - - - - + - - - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -360,7 +338,7 @@ performance - 1.0 + 1.0 diff --git a/applications/adjoint_tests/example/mesh_C12.nc b/applications/adjoint_tests/example/mesh_C12_MG.nc similarity index 64% rename from applications/adjoint_tests/example/mesh_C12.nc rename to applications/adjoint_tests/example/mesh_C12_MG.nc index f7ea6988e..ebe518907 100644 Binary files a/applications/adjoint_tests/example/mesh_C12.nc and b/applications/adjoint_tests/example/mesh_C12_MG.nc differ diff --git a/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/version30_31.py b/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/version30_31.py new file mode 100644 index 000000000..3c1561ee7 --- /dev/null +++ b/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/version30_31.py @@ -0,0 +1,284 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint_tests + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/versions.py b/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/versions.py +++ b/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/vn3.1/rose-meta.conf b/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/vn3.1/rose-meta.conf new file mode 100644 index 000000000..4f4db0daa --- /dev/null +++ b/applications/adjoint_tests/rose-meta/lfric-adjoint_tests/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-adjoint/vn3.1 diff --git a/applications/adjoint_tests/source/adjoint_tests.f90 b/applications/adjoint_tests/source/adjoint_tests.f90 index 2118e5f2c..b24cf8800 100644 --- a/applications/adjoint_tests/source/adjoint_tests.f90 +++ b/applications/adjoint_tests/source/adjoint_tests.f90 @@ -10,7 +10,7 @@ program adjoint_tests - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use driver_collections_mod, only : init_collections, final_collections use driver_comm_mod, only : init_comm, final_comm use driver_config_mod, only : init_config, final_config @@ -24,15 +24,23 @@ program adjoint_tests use log_mod, only : log_event, & log_level_trace, & log_scratch_space + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path + use namelist_mod, only: namelist_type implicit none ! Model run working data set type (modeldb_type) :: modeldb - character(*), parameter :: application_name = "adjoint_tests" - character(:), allocatable :: filename + character(*), parameter :: application_name = "adjoint_tests" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + + logical :: lsubroutine_timers + + call parse_command_line( filename ) modeldb%mpi => global_mpi call modeldb%configuration%initialise( application_name, table_len=10 ) @@ -55,10 +63,17 @@ program adjoint_tests call modeldb%io_contexts%initialise(application_name, 100) call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) + call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) + + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, & + application_name, timer_output_path ) + nullify( io_nml ) + call init_collections() call init_time( modeldb ) deallocate( filename ) @@ -75,6 +90,7 @@ program adjoint_tests call final_time( modeldb ) call final_collections() + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 new file mode 100644 index 000000000..c1294aa55 --- /dev/null +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bdy_lyr_alg_mod.x90 @@ -0,0 +1,192 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Module containing adjoint test for atl_bdy_lyr_alg +module atlt_bdy_lyr_alg_mod + + use sci_assign_field_random_range_alg_mod, & + only : assign_field_random_range + use field_mod, only : field_type + use function_space_mod, only : function_space_type + use constants_mod, only : r_def, i_def, l_def + use field_indices_mod, only : igh_u, igh_t, & + igh_d, igh_p + use log_mod, only : log_event, & + log_scratch_space, & + LOG_LEVEL_INFO, & + LOG_LEVEL_DEBUG, & + LOG_LEVEL_ERROR + use mesh_mod, only : mesh_type + use derived_config_mod, only : bundle_size + use driver_modeldb_mod, only : modeldb_type + use finite_element_config_mod, only : element_order_h, element_order_v + use fs_continuity_mod, only : W2, W3, Wtheta + use function_space_collection_mod, only : function_space_collection + use adjoint_test_parameters_mod, only : ls_u_range, ls_theta_range, & + ls_rho_range, ls_exner_range + use timing_mod, only : start_timing, stop_timing, tik, LPROF + + implicit none + + public + + contains + + !============================================================================= + !> @brief Adjoint test for atl_bdy_lyr_alg. + !> @details Passes if adjoint is transpose of tangent linear. + !> Determined by testing the equality of inner products and , + !> where M is the tangent linear and A is the adjoint. + !> @param[in,out] modeldb Structure containing the model state + !> @param[in] mesh The model mesh + subroutine atlt_bdy_lyr_alg( modeldb, mesh ) + + use tl_bdy_lyr_alg_mod, only : tl_bdy_lyr_alg + use atl_bdy_lyr_alg_mod, only : atl_bdy_lyr_alg + + implicit none + + ! Arguments + type(modeldb_type), target, intent(inout) :: modeldb + type(mesh_type), pointer, intent(in) :: mesh + + ! Arguments for tl and atl calls + ! Form of state is [u,theta,rho,exner] + type(field_type) :: state(bundle_size) + type(field_type) :: u_bl_inc + type(field_type) :: ls_state(bundle_size) + + ! Copies of input fields used in inner products + type(field_type) :: state_input(bundle_size) + type(field_type) :: u_bl_inc_input + + ! Pointers for initialising fields + type(function_space_type), pointer :: vector_space_wtheta_ptr + type(function_space_type), pointer :: vector_space_w2_ptr + type(function_space_type), pointer :: vector_space_w3_ptr + + ! Inner products + real(kind=r_def) :: inner1 + real(kind=r_def) :: inner2 + real(kind=r_def) :: ip1(2),ip2(2) + real(kind=r_def) :: sf(2) + + ! Test parameters and variables + real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def + real(kind=r_def) :: machine_tol + real(kind=r_def) :: relative_diff + real(kind=r_def), parameter :: eps = 1e-30_r_def + + ! Misc + real(kind=r_def) :: dt + + integer(kind=tik) :: id + + if ( LPROF ) call start_timing( id, 'atlt_bdy_lyr_alg' ) + + ! Determining time constants + dt = real(modeldb%clock%get_seconds_per_step(), r_def) + if ( dt <= 0.0_r_def ) then + write( log_scratch_space, * ) "dt cannot be leq 0, found dt = ", dt + call log_event( log_scratch_space, log_level_error ) + end if + + ! Initialising fields + vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) + vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) + vector_space_w3_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W3 ) + + call state(igh_u) % initialise( vector_space = vector_space_w2_ptr ) + call state(igh_t) % initialise( vector_space = vector_space_wtheta_ptr ) + call state(igh_d) % initialise( vector_space = vector_space_w3_ptr ) + call state(igh_p) % initialise( vector_space = vector_space_w3_ptr ) + call u_bl_inc % initialise( vector_space = vector_space_w2_ptr ) + + call state(igh_u) % copy_field_properties( state_input(igh_u) ) + call state(igh_t) % copy_field_properties( state_input(igh_t) ) + call state(igh_d) % copy_field_properties( state_input(igh_d) ) + call state(igh_p) % copy_field_properties( state_input(igh_p) ) + call state(igh_u) % copy_field_properties( u_bl_inc_input ) + + call state(igh_u) % copy_field_properties( ls_state(igh_u) ) + call state(igh_t) % copy_field_properties( ls_state(igh_t) ) + call state(igh_d) % copy_field_properties( ls_state(igh_d) ) + call state(igh_p) % copy_field_properties( ls_state(igh_p) ) + + ! Initialise values and call the tangent-linear alg. + call invoke( setval_random( u_bl_inc ), & + setval_x(u_bl_inc_input, u_bl_inc ), & + setval_random( state(igh_u) ), & + setval_x( state_input(igh_u), state(igh_u) ), & + setval_random( state(igh_t) ), & + setval_x( state_input(igh_t), state(igh_t) ), & + setval_random( state(igh_d) ), & + setval_x( state_input(igh_d), state(igh_d) ), & + setval_random( state(igh_p) ), & + setval_x( state_input(igh_p), state(igh_p) ) ) + + ! LS init + call assign_field_random_range( ls_state(igh_u), ls_u_range(1), ls_u_range(2) ) + call assign_field_random_range( ls_state(igh_t), ls_theta_range(1), ls_theta_range(2) ) + call invoke( setval_random( ls_state(igh_d) ), setval_random( ls_state(igh_p) ) ) + + ! Tangent linear + call tl_bdy_lyr_alg(modeldb, u_bl_inc, state(igh_u), ls_state, dt ) + + ! < Mx, Mx > + call invoke( x_innerproduct_x( ip1(1), state(igh_u) ), & + x_innerproduct_x( ip1(2), u_bl_inc ) ) + + sf(1) = 1.0_r_def / (ip1(1) + eps) + sf(2) = 1.0_r_def / (ip1(2) + eps) + + inner1 = 0.0_r_def + inner1 = inner1 + ip1(1) * sf(1) + inner1 = inner1 + ip1(2) * sf(2) + + ! Scaling fields + call invoke( inc_a_times_X( sf(1), state(igh_u) ), & + inc_a_times_X( sf(2), u_bl_inc ) ) + + ! Adjoint alg call and inner products + + ! Adjoint + call atl_bdy_lyr_alg(modeldb, u_bl_inc, state(igh_u), ls_state, dt ) + + ! < AMx, x > + call invoke( x_innerproduct_y( ip2(1), & + state(igh_u), & + state_input(igh_u) ), & + x_innerproduct_y( ip2(2), & + u_bl_inc, & + u_bl_inc_input ) ) + + inner2 = 0.0_r_def + inner2 = inner2 + ip2(1) + inner2 = inner2 + ip2(2) + + write( log_scratch_space, * ) 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip1=', ip1(1) * sf(1), ip1(2) * sf(2) + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: ip2=', ip2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bdy_lyr_alg: ad test for tl_bdy_lyr_alg: s(ip1),s(ip2)=', inner1, inner2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + ! Test the inner-product values for equality, allowing for the precision of the active variables + machine_tol = spacing( max( abs( inner1 ), abs( inner2 ) ) ) + relative_diff = abs( inner1 - inner2 ) / machine_tol + if ( relative_diff < overall_tolerance ) then + write( log_scratch_space, * ) "PASSED tl_bdy_lyr_alg:", inner1, inner2, relative_diff + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + else + write( log_scratch_space, * ) "FAILED tl_bdy_lyr_alg:", inner1, inner2, relative_diff + call log_event( log_scratch_space, LOG_LEVEL_ERROR ) + end if + + if ( LPROF ) call stop_timing( id, 'atlt_bdy_lyr_alg' ) + + end subroutine atlt_bdy_lyr_alg + +end module atlt_bdy_lyr_alg_mod diff --git a/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 new file mode 100644 index 000000000..c617ba147 --- /dev/null +++ b/applications/adjoint_tests/source/algorithm/linear_physics/atlt_bl_inc_alg_mod.x90 @@ -0,0 +1,187 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Module containing adjoint test for atl_bl_inc_kernel +module atlt_bl_inc_alg_mod + + use sci_assign_field_random_range_alg_mod, & + only : assign_field_random_range + use sci_geometric_constants_mod, only: get_face_selector_ew, & + get_face_selector_ns + use integer_field_mod, only: integer_field_type + use field_mod, only : field_type + use function_space_mod, only : function_space_type + use log_mod, only : log_event, & + log_scratch_space, & + LOG_LEVEL_ERROR, & + LOG_LEVEL_DEBUG, & + LOG_LEVEL_INFO + use mesh_mod, only : mesh_type + use function_space_collection_mod, only : function_space_collection + use finite_element_config_mod, only : element_order_h, element_order_v + use fs_continuity_mod, only : W2, W3, Wtheta + use constants_mod, only : i_def, r_def + use quadrature_face_mod, only : quadrature_face_type + use quadrature_rule_gaussian_mod, only : quadrature_rule_gaussian_type + use reference_element_mod, only : reference_element_type + use planet_config_mod, only : cp + use adjoint_test_parameters_mod, only : ls_theta_range, & + ls_exner_range, & + ls_md1_range, & + ls_md2_range, & + ls_md3_range + use timing_mod, only : start_timing, stop_timing, tik, LPROF + + implicit none + + public + + contains + + !============================================================================= + !> @brief Adjoint test for atl_bl_inc. + !> @details Passes if adjoint is transpose of tangent linear. + !> Determined by testing the equality of inner products and , + !> where M is the tangent linear and A is the adjoint. + !> @param[in] mesh Mesh object + subroutine atlt_bl_inc_alg( mesh ) + + use tl_bl_inc_kernel_mod, only : tl_bl_inc_kernel_type + use atl_bl_inc_kernel_mod, only : atl_bl_inc_kernel_type + use linear_physics_config_mod, only : log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m + + implicit none + + ! Arguments + type(mesh_type), pointer, intent(in) :: mesh + + ! Arguments for tl and adj calls + type( field_type) :: u_inc + type( field_type) :: u + type( field_type) :: auv + type( field_type) :: buv_inv + type(integer_field_type), pointer :: face_selector_ew => null() + type(integer_field_type), pointer :: face_selector_ns => null() + + ! Copies of input fields used in inner products + type( field_type) :: u_inc_input + type( field_type) :: u_input + + ! Pointers for initialising fields + type(function_space_type), pointer :: vector_space_wtheta_ptr + type(function_space_type), pointer :: vector_space_w2_ptr + type(function_space_type), pointer :: vector_space_w3_ptr + + ! Inner products + real(kind=r_def) :: ip1(2) + real(kind=r_def) :: ip2(2) + real(kind=r_def) :: sf(2) + real(kind=r_def) :: inner1 + real(kind=r_def) :: inner2 + + ! Test parameters and variables + real(kind=r_def), parameter :: overall_tolerance = 3000.0_r_def + real(kind=r_def) :: machine_tol + real(kind=r_def) :: relative_diff + real(kind=r_def), parameter :: eps = 1e-30_r_def + + integer(kind=tik) :: id + + if ( LPROF ) call start_timing( id, 'atlt_bl_inc_alg' ) + + vector_space_wtheta_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, Wtheta ) + vector_space_w2_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W2 ) + vector_space_w3_ptr => function_space_collection % get_fs( mesh, element_order_h, element_order_v, W3 ) + + call auv % initialise( vector_space = vector_space_w2_ptr, name = 'auv' ) + call buv_inv % initialise( vector_space = vector_space_w2_ptr, name = 'buv_inv' ) + + call u_inc % initialise( vector_space = vector_space_w2_ptr, name = 'u_inc' ) + call u % initialise( vector_space = vector_space_w2_ptr, name = 'u' ) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + call u_inc % copy_field_properties( u_inc_input ) + call u % copy_field_properties( u_input ) + + ! Initialise arguments and call the tangent-linear kernel. + call invoke( setval_random( u ), & + setval_x( u_input, u ), & + setval_random( u_inc ), & + setval_x( u_inc_input, u_inc ) ) + + ! LS init + call assign_field_random_range( auv, -1.0_r_def, 1.0_r_def ) + call assign_field_random_range( buv_inv, 1.0_r_def, 2.0_r_def ) ! must avoid 0 + + ! < Mx, Mx > + call invoke ( tl_bl_inc_kernel_type( u_inc, & + u, & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + call invoke ( x_innerproduct_x( ip1(1), u_inc ), & + x_innerproduct_x( ip1(2), u ) ) + + sf(1) = 1.0_r_def / (ip1(1) + eps) + sf(2) = 1.0_r_def / (ip1(2) + eps) + + inner1 = 0.0_r_def + inner1 = inner1 + ip1(1) * sf(1) + inner1 = inner1 + ip1(2) * sf(2) + + ! Scaling fields + call invoke( inc_a_times_X( sf(1), u_inc ), & + inc_a_times_X( sf(2), u ) ) + + ! < AMx, x > + call invoke ( atl_bl_inc_kernel_type( u_inc, & + u, & + auv,buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m ) ) + + call invoke ( x_innerproduct_y( ip2(1), u_inc, u_inc_input ), & + x_innerproduct_y( ip2(2), u, u_input ) ) + + inner2 = 0.0_r_def + inner2 = inner2 + ip2(1) + inner2 = inner2 + ip2(2) + + write( log_scratch_space, * ) 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip1=', & + ip1(1) * sf(1), ip1(2) * sf(2) + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: ip2=', ip2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + write( log_scratch_space, * ) 'atlt_bl_inc_alg: ad test for atl_bl_inc_kernel_type: s(ip1),s(ip2)=', & + inner1, inner2 + call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) + + ! Test the inner-product values for equality, allowing for the precision of the active variables + machine_tol = spacing( max( abs(inner1), abs(inner2) ) ) + relative_diff = abs(inner1 - inner2) / machine_tol + if (relative_diff < overall_tolerance) then + write(log_scratch_space, *) "PASSED tl_bl_inc:", inner1, inner2, relative_diff + call log_event(log_scratch_space, LOG_LEVEL_INFO) + else + write(log_scratch_space, *) "FAILED tl_bl_inc:", inner1, inner2, relative_diff + call log_event(log_scratch_space, LOG_LEVEL_ERROR) + end if + + if ( LPROF ) call stop_timing( id, 'atlt_bl_inc_alg' ) + + end subroutine atlt_bl_inc_alg + +end module atlt_bl_inc_alg_mod diff --git a/applications/adjoint_tests/source/algorithm/lookup/solver/adjt_apply_helmholtz_op_lookup_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/lookup/solver/adjt_apply_helmholtz_op_lookup_alg_mod.x90 index d2bafff51..57745e301 100644 --- a/applications/adjoint_tests/source/algorithm/lookup/solver/adjt_apply_helmholtz_op_lookup_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/lookup/solver/adjt_apply_helmholtz_op_lookup_alg_mod.x90 @@ -9,6 +9,7 @@ !> @brief Module containing adjoint test for adj_apply_helmholtz_op_lookup_kernel module adjt_apply_helmholtz_op_lookup_alg_mod + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type use constants_mod, only: i_def, r_def, l_def, r_solver use field_mod, only: field_type use finite_element_config_mod, only: element_order_h, element_order_v @@ -39,19 +40,20 @@ module adjt_apply_helmholtz_op_lookup_alg_mod !! the result stored in the other, so we use three vectors to save on !! variables. This differs from other adjoint tests as most adjoint !! routines would increment one argument and set the other to zero. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine adjt_apply_helmholtz_op_lookup_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache The lookup table cache + subroutine adjt_apply_helmholtz_op_lookup_alg( mesh, model_clock, adj_lookup_table_cache ) - use apply_helmholtz_operator_kernel_mod, only: apply_helmholtz_operator_kernel_type - use adj_lookup_table_generators_alg_mod, only: create_lookup_apply_helmholtz_op + use apply_helmholtz_operator_kernel_mod, only: apply_helmholtz_operator_kernel_type use invoke_adj_a_h_o_lookup_kernel_mod, only: invoke_adj_a_h_o_lookup_kernel implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_solver_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Randomised prognostics to initialise SI operators type(field_type) :: init_op_t, init_op_d, init_op_p, init_op_moist_dyn(num_moist_factors) @@ -67,13 +69,14 @@ module adjt_apply_helmholtz_op_lookup_alg_mod ! Configuration logical(kind=l_def) :: lam_mesh integer(kind=i_def), parameter :: stencil_extent = 1_i_def + integer(kind=i_def), parameter :: level = 1_i_def type(r_solver_field_type), pointer :: Helmholtz_operator(:) ! Lookup table - type(adj_lookup_table_type) :: lookup - type(integer_field_type), pointer :: lookup_field - type(integer_field_type), pointer :: set_counts_field - integer(kind=i_def) :: nindices + type(adj_lookup_table_type), pointer :: lookup + type(integer_field_type), pointer :: lookup_field + type(integer_field_type), pointer :: set_counts_field + integer(kind=i_def) :: nindices ! Inner products real(kind=r_def) :: vector_mx_vector_mx_inner_prod @@ -87,7 +90,7 @@ module adjt_apply_helmholtz_op_lookup_alg_mod real(kind=r_def) :: relative_diff real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def - nullify( lookup_field, set_counts_field, Helmholtz_operator, & + nullify( lookup, lookup_field, set_counts_field, Helmholtz_operator, & vector_space_w3_ptr, vector_space_wtheta_ptr ) ! Setup @@ -113,7 +116,7 @@ module adjt_apply_helmholtz_op_lookup_alg_mod call compute_si_operators( init_op_t, init_op_d, init_op_p, model_clock, init_op_moist_dyn ) - Helmholtz_operator => get_helmholtz_operator(stencil_extent) + Helmholtz_operator => get_helmholtz_operator(level) lam_mesh = .false. call vector_x%initialise(vector_space_w3_ptr) @@ -144,8 +147,7 @@ module adjt_apply_helmholtz_op_lookup_alg_mod ! Adjoint (AMx) - ! Create lookup table. - call create_lookup_apply_helmholtz_op( lookup, vector_mx ) + lookup => adj_lookup_table_cache%get_lookup_apply_hho(level) lookup_field => lookup%get_lookup_field() set_counts_field => lookup%get_set_count_field() nindices = lookup%get_nindices() diff --git a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly1d_recon_lookup_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly1d_recon_lookup_alg_mod.x90 index 8748d5717..c8b3833f5 100644 --- a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly1d_recon_lookup_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly1d_recon_lookup_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for adj_poly1d_recon_lookup_kernel module adjt_poly1d_recon_lookup_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use integer_field_mod, only : integer_field_type use function_space_mod, only : function_space_type use function_space_collection_mod, only : function_space_collection @@ -16,7 +17,7 @@ module adjt_poly1d_recon_lookup_alg_mod use r_tran_field_mod, only : r_tran_field_type use mesh_mod, only : mesh_type use fs_continuity_mod, only : Wtheta - use constants_mod, only : i_def, r_def, r_tran + use constants_mod, only : i_def, r_def, r_tran, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -35,17 +36,18 @@ module adjt_poly1d_recon_lookup_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - subroutine adjt_poly1d_recon_lookup_alg( mesh ) + !> @param[in] mesh The model mesh + !> @param[in] adj_lookup_table_cache The lookup table cache + subroutine adjt_poly1d_recon_lookup_alg( mesh, adj_lookup_table_cache ) use poly1d_reconstruction_kernel_mod, only : poly1d_reconstruction_kernel_type - use adj_lookup_table_generators_alg_mod, only : create_lookup_poly1d use invoke_adj_poly1d_recon_lookup_mod, only : invoke_adj_poly1d_recon_lookup implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh + type(mesh_type), pointer, intent(in) :: mesh + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal arguments for kernels type(r_tran_field_type) :: reconstruction @@ -55,7 +57,7 @@ module adjt_poly1d_recon_lookup_alg_mod type(r_tran_field_type), pointer :: coeff integer(kind=i_def) :: ndata integer(kind=i_def) :: order - type(adj_lookup_table_type) :: lookup_poly1d + type(adj_lookup_table_type), pointer :: lookup_poly1d type(integer_field_type), pointer :: lookup_poly1d_field type(integer_field_type), pointer :: num_sets_poly1d_field integer(kind=i_def) :: nsets @@ -77,14 +79,13 @@ module adjt_poly1d_recon_lookup_alg_mod real(kind=r_def) :: reconstruction_reconstruction_input_inner_prod real(kind=r_def) :: tracer_tracer_input_inner_prod real(kind=r_tran) :: inner2 - real(kind=r_tran), parameter :: eps = 1e-30_r_def ! Test parameters and variables - real(kind=r_tran), parameter :: overall_tolerance = 1500.0_r_tran + real(kind=r_tran), parameter :: overall_tolerance = 2500.0_r_tran real(kind=r_tran) :: machine_tol real(kind=r_tran) :: relative_diff - nullify(coeff, lookup_poly1d_field, num_sets_poly1d_field, & + nullify(coeff, lookup_poly1d, lookup_poly1d_field, num_sets_poly1d_field, & vector_space_wtheta_ptr, vector_space_wt_md_ptr) mesh_id = mesh%get_id() @@ -121,8 +122,8 @@ module adjt_poly1d_recon_lookup_alg_mod x_innerproduct_x( tracer_inner_prod, tracer ) ) ! Determining scale factors - reconstruction_sf = 1.0_r_tran/( real( reconstruction_inner_prod, r_tran ) + eps ) - tracer_sf = 1.0_r_tran/( real( tracer_inner_prod, r_tran ) + eps ) + reconstruction_sf = 1.0_r_tran/( real( reconstruction_inner_prod, r_tran ) + EPS ) + tracer_sf = 1.0_r_tran/( real( tracer_inner_prod, r_tran ) + EPS ) inner1 = 0.0_r_tran inner1 = inner1 + real( reconstruction_inner_prod, r_tran )*reconstruction_sf @@ -141,7 +142,7 @@ module adjt_poly1d_recon_lookup_alg_mod reconstruction_reconstruction_input_inner_prod = 0.0_r_def tracer_tracer_input_inner_prod = 0.0_r_def - call create_lookup_poly1d( lookup_poly1d, reconstruction, tracer, coeff, stencil_extent, order ) + lookup_poly1d => adj_lookup_table_cache%get_lookup_poly1d() lookup_poly1d_field => lookup_poly1d%get_lookup_field() num_sets_poly1d_field => lookup_poly1d%get_set_count_field() nindices = lookup_poly1d%get_nindices() diff --git a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly2d_recon_lookup_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly2d_recon_lookup_alg_mod.x90 index 0bfc5f58c..8d9ff6466 100644 --- a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly2d_recon_lookup_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly2d_recon_lookup_alg_mod.x90 @@ -4,7 +4,11 @@ ! under which the code may be used. !----------------------------------------------------------------------------- !> @brief Module containing adjoint test for adj_poly2d_recon_lookup_kernel + module adjt_poly2d_recon_lookup_alg_mod + + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type + use integer_field_mod, only : integer_field_type use r_tran_field_mod, only : r_tran_field_type use function_space_mod, only : function_space_type use mesh_mod, only : mesh_type @@ -12,7 +16,7 @@ module adjt_poly2d_recon_lookup_alg_mod use fs_continuity_mod, only : name_from_functionspace use finite_element_config_mod, only : element_order_h, & element_order_v - use constants_mod, only : i_def, r_def, r_tran + use constants_mod, only : i_def, r_def, r_tran, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -20,6 +24,7 @@ module adjt_poly2d_recon_lookup_alg_mod log_scratch_space use transport_config_mod, only : fv_horizontal_order use transport_constants_mod, only : get_hori_wt_mol_coeffs + use adj_lookup_table_mod, only : adj_lookup_table_type implicit none @@ -32,20 +37,20 @@ module adjt_poly2d_recon_lookup_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] fspace_enum The function space to test. - subroutine adjt_poly2d_recon_lookup_alg( mesh, fspace_enum ) + !> @param[in] mesh The model mesh + !> @param[in] fspace_enum The function space to test + !> @param[in] adj_lookup_table_cache The lookup table cache + subroutine adjt_poly2d_recon_lookup_alg( mesh, fspace_enum, adj_lookup_table_cache ) use poly2d_reconstruction_kernel_mod, only : poly2d_reconstruction_kernel_type use invoke_adj_poly2d_recon_lookup_mod, only : invoke_adj_poly2d_recon_lookup - use adj_lookup_table_mod, only : adj_lookup_table_type - use adj_lookup_table_generators_alg_mod, only : create_lookup_poly2d - use integer_field_mod, only : integer_field_type implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - integer(kind=i_def), intent(in) :: fspace_enum + type(mesh_type), pointer, intent(in) :: mesh + integer(kind=i_def), intent(in) :: fspace_enum + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache + ! Internal arguments for kernels type(r_tran_field_type) :: reconstruction @@ -64,11 +69,11 @@ module adjt_poly2d_recon_lookup_alg_mod type(r_tran_field_type) :: tracer_input ! Lookup table variables - type(adj_lookup_table_type) :: lookup - type(integer_field_type), pointer :: lookup_field - type(integer_field_type), pointer :: num_sets_field - integer(kind=i_def) :: nsets - integer(kind=i_def) :: nindices + type(adj_lookup_table_type), pointer :: lookup + type(integer_field_type), pointer :: lookup_field + type(integer_field_type), pointer :: num_sets_field + integer(kind=i_def) :: nsets + integer(kind=i_def) :: nindices ! Inner product variables real(kind=r_def) :: reconstruction_inner_prod @@ -79,7 +84,6 @@ module adjt_poly2d_recon_lookup_alg_mod real(kind=r_def) :: reconstruction_reconstruction_input_inner_prod real(kind=r_def) :: tracer_tracer_input_inner_prod real(kind=r_tran) :: inner2 - real(kind=r_tran), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_tran), parameter :: overall_tolerance = 1500.0_r_tran @@ -87,7 +91,7 @@ module adjt_poly2d_recon_lookup_alg_mod real(kind=r_tran) :: relative_diff nullify(coeff, vector_space_wt_md_ptr, vector_space_wtheta_ptr, & - lookup_field, num_sets_field) + lookup, lookup_field, num_sets_field) mesh_id = mesh%get_id() if (mod(fv_horizontal_order, 2) == 0) then @@ -126,8 +130,8 @@ module adjt_poly2d_recon_lookup_alg_mod x_innerproduct_x( tracer_inner_prod, tracer ) ) ! Determining scale factors - reconstruction_sf = 1.0_r_tran/( real( reconstruction_inner_prod, r_tran ) + eps ) - tracer_sf = 1.0_r_tran/( real( tracer_inner_prod, r_tran ) + eps ) + reconstruction_sf = 1.0_r_tran/( real( reconstruction_inner_prod, r_tran ) + EPS ) + tracer_sf = 1.0_r_tran/( real( tracer_inner_prod, r_tran ) + EPS ) inner1 = 0.0_r_tran inner1 = inner1 + real( reconstruction_inner_prod, r_tran )*reconstruction_sf @@ -146,8 +150,7 @@ module adjt_poly2d_recon_lookup_alg_mod reconstruction_reconstruction_input_inner_prod = 0.0_r_def tracer_tracer_input_inner_prod = 0.0_r_def - call create_lookup_poly2d( lookup, reconstruction, tracer, coeff, & - stencil_size, stencil_extent ) + lookup => adj_lookup_table_cache%get_lookup_poly2d(fspace_enum) lookup_field => lookup%get_lookup_field() num_sets_field => lookup%get_set_count_field() nindices = lookup%get_nindices() diff --git a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly_adv_upd_lookup_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly_adv_upd_lookup_alg_mod.x90 index b95eb5823..311c89b38 100644 --- a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly_adv_upd_lookup_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_poly_adv_upd_lookup_alg_mod.x90 @@ -7,6 +7,7 @@ module adjt_poly_adv_upd_lookup_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use function_space_mod, only : function_space_type use function_space_collection_mod, only : function_space_collection @@ -17,7 +18,7 @@ module adjt_poly_adv_upd_lookup_alg_mod use integer_field_mod, only : integer_field_type, & integer_field_proxy_type use fs_continuity_mod, only : W2H, Wtheta - use constants_mod, only : i_def, r_def, r_tran, l_def + use constants_mod, only : i_def, r_def, r_tran, l_def, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -33,19 +34,18 @@ module adjt_poly_adv_upd_lookup_alg_mod !============================================================================! !> @brief Handwritten adjoint test for adj_poly_adv_upd_lookup_kernel - !> @param[in] mesh Model mesh - subroutine adjt_poly_adv_upd_lookup_alg( mesh ) + !> @param[in] mesh Model mesh + !> @param[in] adj_lookup_table_cache The lookup table cache + subroutine adjt_poly_adv_upd_lookup_alg( mesh, adj_lookup_table_cache ) use poly_adv_update_kernel_mod, only: poly_adv_update_kernel_type use invoke_adj_poly_adv_upd_lookup_mod, only: invoke_adj_poly_adv_upd_lookup - use adj_lookup_table_generators_alg_mod, only : create_lookup_poly_adv_upd - use invoke_adj_poly_adv_upd_lookup_mod, only : invoke_adj_poly_adv_upd_lookup - implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh + type(mesh_type), pointer, intent(in) :: mesh + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables ! Input setup variables @@ -55,7 +55,7 @@ module adjt_poly_adv_upd_lookup_alg_mod integer(kind=i_def), parameter :: stencil_extent = 1_i_def integer(kind=i_def), parameter :: ndata = 4_i_def - type(adj_lookup_table_type) :: lookup_poly_adv_upd + type(adj_lookup_table_type), pointer :: lookup_poly_adv_upd type(integer_field_type), pointer :: lookup_poly_adv_upd_field type(integer_field_type), pointer :: num_sets_poly_adv_upd_field @@ -81,16 +81,16 @@ module adjt_poly_adv_upd_lookup_alg_mod real(kind=r_def) :: advective_advective_input_inner_prod real(kind=r_def) :: reconstruction_reconstruction_input_inner_prod real(kind=r_tran) :: inner2 - real(kind=r_tran), parameter :: eps = 1e-30_r_tran ! Test variables real(kind=r_tran), parameter :: overall_tolerance = 1500.0_r_tran real(kind=r_tran) :: machine_tol real(kind=r_tran) :: relative_diff - nullify( vector_space_w2h_ptr, & - vector_space_wt_md_ptr, & - vector_space_wtheta_ptr, & + nullify( vector_space_w2h_ptr, & + vector_space_wt_md_ptr, & + vector_space_wtheta_ptr, & + lookup_poly_adv_upd, & lookup_poly_adv_upd_field, & num_sets_poly_adv_upd_field ) @@ -124,8 +124,8 @@ module adjt_poly_adv_upd_lookup_alg_mod x_innerproduct_x( reconstruction_inner_prod, reconstruction) ) ! Determining scale factors - advective_sf = 1.0_r_tran/( real( advective_inner_prod, r_tran ) + eps ) - reconstruction_sf = 1.0_r_tran/( real( reconstruction_inner_prod, r_tran ) + eps ) + advective_sf = 1.0_r_tran/( real( advective_inner_prod, r_tran ) + EPS ) + reconstruction_sf = 1.0_r_tran/( real( reconstruction_inner_prod, r_tran ) + EPS ) inner1 = 0.0_r_tran inner1 = inner1 + real( advective_inner_prod, r_tran )*advective_sf @@ -144,8 +144,7 @@ module adjt_poly_adv_upd_lookup_alg_mod advective_advective_input_inner_prod = 0.0_r_def reconstruction_reconstruction_input_inner_prod = 0.0_r_def - call create_lookup_poly_adv_upd( lookup_poly_adv_upd, advective, reconstruction, & - wind, stencil_extent ) + lookup_poly_adv_upd => adj_lookup_table_cache%get_lookup_poly_adv_upd() lookup_poly_adv_upd_field => lookup_poly_adv_upd%get_lookup_field() num_sets_poly_adv_upd_field => lookup_poly_adv_upd%get_set_count_field() nindices = lookup_poly_adv_upd%get_nindices() diff --git a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_w3h_adv_upd_lookup_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_w3h_adv_upd_lookup_alg_mod.x90 index 60a2ee48d..112891ecb 100644 --- a/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_w3h_adv_upd_lookup_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/lookup/transport/mol/adjt_w3h_adv_upd_lookup_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for adj_w3h_adv_upd_lookup_lookup_kernel module adjt_w3h_adv_upd_lookup_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use integer_field_mod, only : integer_field_type use r_tran_field_mod, only : r_tran_field_type use fs_continuity_mod, only : W3, W2 @@ -15,7 +16,7 @@ module adjt_w3h_adv_upd_lookup_alg_mod use function_space_collection_mod, only : function_space_collection use finite_element_config_mod, only : element_order_h, element_order_V use operator_mod, only : operator_type - use constants_mod, only : i_def, r_def, r_tran + use constants_mod, only : i_def, r_def, r_tran, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -35,26 +36,25 @@ module adjt_w3h_adv_upd_lookup_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] lookup_collection Lookup table collection object containing read and write indices - !! for stencil adjoints - subroutine adjt_w3h_adv_upd_lookup_alg( mesh ) + !> @param[in] mesh The model mesh + !> @param[in] adj_lookup_table_cache The lookup table cache + subroutine adjt_w3h_adv_upd_lookup_alg( mesh, adj_lookup_table_cache ) use w3h_advective_update_kernel_mod, only : w3h_advective_update_kernel_type use invoke_adj_w3h_adv_upd_lookup_mod, only : invoke_adj_w3h_adv_upd_lookup_kernel_type - use adj_lookup_table_generators_alg_mod, only : create_lookup_w3h_adv_upd implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh + type(mesh_type), pointer, intent(in) :: mesh + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal arguments for kernels type(r_tran_field_type) :: advective_increment type(r_tran_field_type) :: tracer type(r_tran_field_type) :: wind type(operator_type), pointer :: m3_inv - type(adj_lookup_table_type) :: lookup_w3h_adv_upd + type(adj_lookup_table_type), pointer :: lookup_w3h_adv_upd type(integer_field_type), pointer :: lookup_w3h_adv_upd_field type(integer_field_type), pointer :: set_count_w3h_adv_upd_field integer(kind=i_def) :: nsets @@ -78,14 +78,13 @@ module adjt_w3h_adv_upd_lookup_alg_mod real(kind=r_def) :: adv_inc_adv_inc_inp_inner_prod real(kind=r_def) :: tracer_tracer_input_inner_prod real(kind=r_tran) :: inner2 - real(kind=r_tran), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_tran), parameter :: overall_tolerance = 1500.0_r_tran real(kind=r_tran) :: machine_tol real(kind=r_tran) :: relative_diff - nullify(m3_inv, lookup_w3h_adv_upd_field, set_count_w3h_adv_upd_field, & + nullify(m3_inv, lookup_w3h_adv_upd, lookup_w3h_adv_upd_field, set_count_w3h_adv_upd_field, & vector_space_w3_md_ptr, vector_space_w3_ptr, vector_space_w2_ptr) vector_space_w3_md_ptr => function_space_collection%get_fs( & @@ -98,7 +97,7 @@ module adjt_w3h_adv_upd_lookup_alg_mod mesh, element_order_h, element_order_v, W2 & ) call advective_increment%initialise( vector_space=vector_space_w3_ptr, name='advective_increment' ) - call tracer%initialise( vector_space=vector_space_w3_md_ptr, name='tracer ') + call tracer%initialise( vector_space=vector_space_w3_md_ptr, name='tracer' ) call wind%initialise( vector_space=vector_space_w2_ptr, name='wind' ) call advective_increment_input%initialise( vector_space=vector_space_w3_ptr, name='advective_increment_input' ) call tracer_input%initialise( vector_space=vector_space_w3_md_ptr, name='tracer_input' ) @@ -125,8 +124,8 @@ module adjt_w3h_adv_upd_lookup_alg_mod x_innerproduct_x(tracer_inner_prod, tracer) ) ! Determining scale factors - advective_increment_sf = 1.0_r_tran/( real( advective_increment_inner_prod, r_tran ) + eps ) - tracer_sf = 1.0_r_tran/( real( tracer_inner_prod, r_tran ) + eps ) + advective_increment_sf = 1.0_r_tran/( real( advective_increment_inner_prod, r_tran ) + EPS ) + tracer_sf = 1.0_r_tran/( real( tracer_inner_prod, r_tran ) + EPS ) inner1 = 0.0_r_tran inner1 = inner1 + real( advective_increment_inner_prod, r_tran )*advective_increment_sf @@ -146,8 +145,7 @@ module adjt_w3h_adv_upd_lookup_alg_mod adv_inc_adv_inc_inp_inner_prod = 0.0_r_def tracer_tracer_input_inner_prod = 0.0_r_def - call create_lookup_w3h_adv_upd( lookup_w3h_adv_upd, advective_increment, tracer, wind, & - m3_inv, stencil_extent ) + lookup_w3h_adv_upd => adj_lookup_table_cache%get_lookup_w3h_adv_upd(wind%which_function_space()) lookup_w3h_adv_upd_field => lookup_w3h_adv_upd%get_lookup_field() set_count_w3h_adv_upd_field => lookup_w3h_adv_upd%get_set_count_field() nsets = lookup_w3h_adv_upd%get_nsets_max() diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_operator_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_operator_alg_mod.x90 index 1ec40ca09..ae617be40 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_operator_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_operator_alg_mod.x90 @@ -7,7 +7,7 @@ module adjt_mixed_operator_alg_mod - use constants_mod, only: i_def, r_def, l_def, r_solver + use constants_mod, only: i_def, r_def, l_def, r_solver, EPS use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_DEBUG, & @@ -27,8 +27,8 @@ module adjt_mixed_operator_alg_mod use mixed_operator_alg_mod, only: mixed_operator_type use adj_mixed_operator_alg_mod, only: adj_mixed_operator_type use adj_semi_implicit_solver_alg_mod, only: construct_solver_state - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use finite_element_config_mod, only: element_order_h, element_order_v use function_space_collection_mod, only: function_space_collection use moist_dyn_mod, only: num_moist_factors @@ -82,10 +82,11 @@ contains real(kind=r_def) :: inner1, inner2 real(kind=r_def) :: machine_tol, machine_tol_r_solver real(kind=r_def) :: relative_diff, relative_diff_r_solver - real(kind=r_def), parameter :: overall_tolerance = 1000.0_r_def - real(kind=r_def), parameter :: eps = 1e-30_r_def + real(kind=r_def), parameter :: overall_tolerance = 2000.0_r_def + integer(kind=tik) :: id + + if ( LPROF ) call start_timing( id, 'adjt_mixed_operator_alg' ) - if (subroutine_timers) call timer('adjt_mixed_operator_alg') ! -------------------------------------------------------------------------- ! Setup @@ -165,9 +166,9 @@ contains write(log_scratch_space, *) "w inner product = ", w_inner_prod call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - p_sf = 1.0_r_def / (p_inner_prod + eps) - uv_sf = 1.0_r_def / (uv_inner_prod + eps) - w_sf = 1.0_r_def / (w_inner_prod + eps) + p_sf = 1.0_r_def / (p_inner_prod + EPS) + uv_sf = 1.0_r_def / (uv_inner_prod + EPS) + w_sf = 1.0_r_def / (w_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + p_inner_prod * p_sf @@ -216,7 +217,7 @@ contains call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end if - if (subroutine_timers) call timer('adjt_mixed_operator_alg') + if ( LPROF ) call stop_timing(id, 'adjt_mixed_operator_alg' ) end subroutine adjt_mixed_operator_alg diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 index 7a4560938..d29d53c46 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_schur_preconditioner_alg_mod.x90 @@ -7,7 +7,8 @@ module adjt_mixed_schur_preconditioner_alg_mod - use constants_mod, only: i_def, r_def, l_def, r_solver + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type + use constants_mod, only: i_def, r_def, l_def, r_solver, EPS use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -22,31 +23,20 @@ module adjt_mixed_schur_preconditioner_alg_mod igh_p, igh_t, igh_d, igh_u use sci_iterative_solver_mod, only: abstract_iterative_solver_type, & bicgstab_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use finite_element_config_mod, only: element_order_h, element_order_v use function_space_collection_mod, only: function_space_collection use copy_field_alg_mod, only: copy_field use driver_modeldb_mod, only: modeldb_type use fs_continuity_mod, only: W2, W3, Wtheta - use mr_indices_mod, only: nummr use si_operators_alg_mod, only: compute_si_operators use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar use sci_preconditioner_mod, only: abstract_preconditioner_type - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use pressure_operator_alg_mod, only: pressure_operator_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type use semi_implicit_solver_alg_mod, only: create_pressure_preconditioner, & @@ -70,41 +60,36 @@ contains !! the result stored in the other, so we use three vectors to save on !! variables. This differs from other adjoint tests as most adjoint !! routines would increment one argument and set the other to zero. - !> @param[in,out] modeldb Structure containing the model state - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine adjt_mixed_schur_preconditioner_alg( modeldb, mesh, model_clock ) + !> @param[in,out] modeldb Structure containing the model state + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine adjt_mixed_schur_preconditioner_alg( modeldb, mesh, model_clock, adj_lookup_table_cache ) implicit none - type(modeldb_type), target, intent(inout) :: modeldb - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(modeldb_type), target, intent(inout) :: modeldb + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_solver_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Prognostic fields type(field_type), dimension(bundle_size) :: rhs type(r_solver_field_type), dimension(bundle_size) :: rhs_rsol ! LS - type(field_type), dimension(bundle_size) :: ls_rdef - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time ! Solver type(pressure_operator_type) :: pressure_operator @@ -122,12 +107,12 @@ contains real(kind=r_def) :: p_sf, uv_sf, w_sf real(kind=r_def) :: p_p_inp_inner_prod, uv_uv_inp_inner_prod, w_w_inp_inner_prod real(kind=r_def) :: inner1, inner2 - real(kind=r_def), parameter :: overall_tolerance = 1000.0_r_def + real(kind=r_def), parameter :: overall_tolerance = 1100.0_r_def real(kind=r_def) :: machine_tol, machine_tol_r_solver real(kind=r_def) :: relative_diff, relative_diff_r_solver - real(kind=r_def), parameter :: eps = 1e-30_r_def + integer(kind=tik) :: id - if (subroutine_timers) call timer('adjt_mixed_schur_preconditioner_alg') + if ( LPROF ) call start_timing( id, 'adjt_mixed_schur_preconditioner_alg' ) ! -------------------------------------------------------------------------- ! Setup @@ -166,60 +151,25 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - call invoke( name="adjt_msp_itr", & - initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test ) ) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - ! Overwrite ls_u with randoms on [0,1] - call invoke( setval_random(ls_u), & - enforce_bc_kernel_type(ls_u) ) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - ! End of LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) call create_pressure_preconditioner( rhs, pressure_operator, pressure_preconditioner ) call create_pressure_solver( pressure_operator, pressure_preconditioner, pressure_solver ) call create_mixed_preconditioner( rhs, pressure_solver, mixed_preconditioner ) - adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( adj_pressure_operator, adj_pressure_preconditioner ) + call create_adj_pressure_preconditioner( rhs, adj_lookup_table_cache, & + adj_pressure_operator, adj_pressure_preconditioner ) call create_adj_pressure_solver( adj_pressure_operator, adj_pressure_preconditioner, adj_pressure_solver ) call create_adj_mixed_preconditioner( rhs, adj_pressure_solver, adj_mixed_preconditioner ) @@ -253,9 +203,9 @@ contains write(log_scratch_space, *) "w inner product = ", w_inner_prod call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - p_sf = 1.0_r_def / (p_inner_prod + eps) - uv_sf = 1.0_r_def / (uv_inner_prod + eps) - w_sf = 1.0_r_def / (w_inner_prod + eps) + p_sf = 1.0_r_def / (p_inner_prod + EPS) + uv_sf = 1.0_r_def / (uv_inner_prod + EPS) + w_sf = 1.0_r_def / (w_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + p_inner_prod * p_sf @@ -305,7 +255,7 @@ contains deallocate( pressure_preconditioner, pressure_solver, mixed_preconditioner, & adj_pressure_preconditioner, adj_pressure_solver, adj_mixed_preconditioner ) - if (subroutine_timers) call timer('adjt_mixed_schur_preconditioner_alg') + if ( LPROF ) call stop_timing( id, 'adjt_mixed_schur_preconditioner_alg' ) end subroutine adjt_mixed_schur_preconditioner_alg diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 index 67317630f..51b712148 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_mixed_solver_alg_mod.x90 @@ -7,7 +7,8 @@ module adjt_mixed_solver_alg_mod - use constants_mod, only: i_def, r_def, l_def, r_solver + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type + use constants_mod, only: i_def, r_def, l_def, r_solver, EPS use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -26,35 +27,24 @@ module adjt_mixed_solver_alg_mod igh_p, igh_t, igh_d, igh_u use mixed_operator_alg_mod, only: mixed_operator_type use adj_mixed_operator_alg_mod, only: adj_mixed_operator_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use finite_element_config_mod, only: element_order_h, element_order_v use function_space_collection_mod, only: function_space_collection use copy_field_alg_mod, only: copy_field use driver_modeldb_mod, only: modeldb_type use solver_constants_mod, only: get_normalisation use fs_continuity_mod, only: W2, W3, Wtheta - use mr_indices_mod, only: nummr use si_operators_alg_mod, only: compute_si_operators use operator_mod, only: operator_type use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar use sci_iterative_solver_mod, only: abstract_iterative_solver_type, & bicgstab_type, & block_gcr_type - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use sci_preconditioner_mod, only: abstract_preconditioner_type use pressure_operator_alg_mod, only: pressure_operator_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type @@ -81,16 +71,18 @@ contains !! the result stored in the other, so we use three vectors to save on !! variables. This differs from other adjoint tests as most adjoint !! routines would increment one argument and set the other to zero. - !> @param[in,out] modeldb Structure containing the model state - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine adjt_mixed_solver_alg( modeldb, mesh, model_clock ) + !> @param[in,out] modeldb Structure containing the model state + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine adjt_mixed_solver_alg( modeldb, mesh, model_clock, adj_lookup_table_cache ) implicit none - type(modeldb_type), target, intent(inout) :: modeldb - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(modeldb_type), target, intent(inout) :: modeldb + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_solver_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Prognostic fields type(field_type) :: rhs(bundle_size) @@ -99,22 +91,15 @@ contains ! LS - type(field_type) :: ls_rdef(bundle_size) - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. - real(kind=r_def) :: initial_time - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr @@ -139,12 +124,12 @@ contains real(kind=r_def) :: p_sf, uv_sf, w_sf real(kind=r_def) :: p_p_inp_inner_prod, uv_uv_inp_inner_prod, w_w_inp_inner_prod real(kind=r_def) :: inner1, inner2 - real(kind=r_def), parameter :: overall_tolerance = 1000.0_r_def + real(kind=r_def), parameter :: overall_tolerance = 1300.0_r_def real(kind=r_def) :: machine_tol, machine_tol_r_solver real(kind=r_def) :: relative_diff, relative_diff_r_solver - real(kind=r_def), parameter :: eps = 1e-30_r_def + integer(tik) :: id - if (subroutine_timers) call timer('adjt_mixed_solver_alg') + if ( LPROF ) call start_timing( id, 'adjt_mixed_solver_alg' ) ! -------------------------------------------------------------------------- ! Setup @@ -195,51 +180,17 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - call invoke(initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test )) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - call invoke(enforce_bc_kernel_type(ls_u)) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - call invoke(enforce_bc_kernel_type(ls_rdef(igh_u))) - - ! End LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) call create_pressure_preconditioner( rhs, pressure_operator, pressure_preconditioner ) @@ -247,8 +198,8 @@ contains call create_mixed_preconditioner( rhs, pressure_solver, mixed_preconditioner ) call create_mixed_solver( mixed_preconditioner, mixed_operator, mixed_solver ) - adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( adj_pressure_operator, adj_pressure_preconditioner ) + call create_adj_pressure_preconditioner( rhs, adj_lookup_table_cache, & + adj_pressure_operator, adj_pressure_preconditioner ) call create_adj_pressure_solver( adj_pressure_operator, adj_pressure_preconditioner, adj_pressure_solver ) call create_adj_mixed_preconditioner( rhs, adj_pressure_solver, adj_mixed_preconditioner ) call create_adj_mixed_solver( adj_mixed_preconditioner, adj_mixed_operator, adj_mixed_solver ) @@ -284,9 +235,9 @@ contains call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) ! Scaling factors are scaled up a bit to avoid numerical issues - p_sf = 1.0E4_r_def / (p_inner_prod + eps) - uv_sf = 1.0E4_r_def / (uv_inner_prod + eps) - w_sf = 1.0E4_r_def / (w_inner_prod + eps) + p_sf = 1.0E4_r_def / (p_inner_prod + EPS) + uv_sf = 1.0E4_r_def / (uv_inner_prod + EPS) + w_sf = 1.0E4_r_def / (w_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + p_inner_prod * p_sf @@ -336,7 +287,7 @@ contains deallocate( pressure_preconditioner, pressure_solver, mixed_preconditioner, mixed_solver, & adj_pressure_preconditioner, adj_pressure_solver, adj_mixed_preconditioner, adj_mixed_solver ) - if (subroutine_timers) call timer('adjt_mixed_solver_alg') + if ( LPROF ) call stop_timing( id, 'adjt_mixed_solver_alg' ) end subroutine adjt_mixed_solver_alg diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 index 225e7610b..ea0c0eb80 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_pressure_precon_alg_mod.x90 @@ -7,7 +7,8 @@ module adjt_pressure_precon_alg_mod - use constants_mod, only: i_def, r_def, l_def, r_solver + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type + use constants_mod, only: i_def, r_def, l_def, r_solver, EPS use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -20,31 +21,20 @@ module adjt_pressure_precon_alg_mod use derived_config_mod, only: bundle_size use field_indices_mod, only: isol_p, isol_u, isol_w, isol_uv, & igh_p, igh_t, igh_d, igh_u - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use finite_element_config_mod, only: element_order_h, element_order_v use function_space_collection_mod, only: function_space_collection use copy_field_alg_mod, only: copy_field use driver_modeldb_mod, only: modeldb_type use fs_continuity_mod, only: W2, W3, Wtheta - use mr_indices_mod, only: nummr use si_operators_alg_mod, only: compute_si_operators use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar use sci_preconditioner_mod, only: abstract_preconditioner_type - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use pressure_operator_alg_mod, only: pressure_operator_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type use semi_implicit_solver_alg_mod, only: create_pressure_preconditioner @@ -64,41 +54,36 @@ contains !! the result stored in the other, so we use three vectors to save on !! variables. This differs from other adjoint tests as most adjoint !! routines would increment one argument and set the other to zero. - !> @param[in,out] modeldb Structure containing the model state - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine adjt_pressure_precon_alg( modeldb, mesh, model_clock ) + !> @param[in,out] modeldb Structure containing the model state + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine adjt_pressure_precon_alg( modeldb, mesh, model_clock, adj_lookup_table_cache ) implicit none - type(modeldb_type), target, intent(inout) :: modeldb - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(modeldb_type), target, intent(inout) :: modeldb + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_solver_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Prognostic fields type(field_type), dimension(bundle_size) :: rhs type(r_solver_field_type), dimension(bundle_size) :: rhs_rsol ! LS - type(field_type), dimension(bundle_size) :: ls_rdef - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time ! Solver type(pressure_operator_type) :: pressure_operator @@ -114,9 +99,9 @@ contains real(kind=r_def), parameter :: overall_tolerance = 1000.0_r_def real(kind=r_def) :: machine_tol, machine_tol_r_solver real(kind=r_def) :: relative_diff, relative_diff_r_solver - real(kind=r_def), parameter :: eps = 1e-30_r_def + integer(tik) :: id - if (subroutine_timers) call timer('adjt_pressure_precon_alg') + if ( LPROF ) call start_timing( id, 'adjt_pressure_precon_alg' ) ! -------------------------------------------------------------------------- ! Setup @@ -155,56 +140,25 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - call invoke( name="adjt_msp_itr", & - initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test ) ) - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - ! Overwrite ls_u with randoms on [0,1] - call invoke( setval_random(ls_u), & - enforce_bc_kernel_type(ls_u) ) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - ! End of LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) call create_pressure_preconditioner( rhs, pressure_operator, pressure_preconditioner ) - adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( adj_pressure_operator, adj_pressure_preconditioner ) + call create_adj_pressure_preconditioner( rhs, & + adj_lookup_table_cache, & + adj_pressure_operator, & + adj_pressure_preconditioner ) ! Size = 1 as only P field needed vector_x = r_solver_field_vector_type(1_i_def) @@ -235,7 +189,7 @@ contains write(log_scratch_space, *) "p inner product = ", p_inner_prod call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - p_sf = 1.0_r_def / (p_inner_prod + eps) + p_sf = 1.0_r_def / (p_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + p_inner_prod * p_sf @@ -276,7 +230,7 @@ contains deallocate( pressure_preconditioner, adj_pressure_preconditioner ) - if (subroutine_timers) call timer('adjt_pressure_preconditioner_alg') + if ( LPROF ) call stop_timing( id, 'adjt_pressure_precon_alg' ) end subroutine adjt_pressure_precon_alg diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_scaled_matrix_vector_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_scaled_matrix_vector_alg_mod.x90 index 81c23dd57..33a2a9f96 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_scaled_matrix_vector_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_scaled_matrix_vector_alg_mod.x90 @@ -9,7 +9,7 @@ !> @brief Module containing adjoint test for scaled_matrix_vector_kernel module adjt_scaled_matrix_vector_alg_mod - use constants_mod, only: i_def, r_def, l_def, r_solver + use constants_mod, only: i_def, r_def, l_def, r_solver, EPS use field_mod, only: field_type use finite_element_config_mod, only: element_order_h, element_order_v use fs_continuity_mod, only: W2, W3, Wtheta @@ -77,7 +77,6 @@ module adjt_scaled_matrix_vector_alg_mod real(kind=r_def) :: machine_tolerance real(kind=r_def) :: relative_diff real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Setup @@ -128,7 +127,7 @@ module adjt_scaled_matrix_vector_alg_mod write(log_scratch_space, *) "vector inner product = ", vector_inner_prod call log_event( log_scratch_space, LOG_LEVEL_DEBUG ) - vector_sf = 1.0_r_def / (vector_inner_prod + eps) + vector_sf = 1.0_r_def / (vector_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + vector_inner_prod * vector_sf diff --git a/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 index 6672c772c..3e61588ff 100644 --- a/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/solver/adjt_semi_implicit_solver_step_alg_mod.x90 @@ -7,7 +7,8 @@ module adjt_semi_implicit_solver_step_alg_mod - use constants_mod, only: i_def, r_def, l_def, r_solver + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type + use constants_mod, only: i_def, r_def, l_def, r_solver, EPS use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -18,8 +19,8 @@ module adjt_semi_implicit_solver_step_alg_mod use derived_config_mod, only: bundle_size use field_indices_mod, only: isol_p, isol_u, isol_w, isol_uv, & igh_p, igh_t, igh_d, igh_u - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use finite_element_config_mod, only: element_order_h, element_order_v use adj_semi_implicit_solver_alg_mod, only: adj_semi_implicit_solver_type use semi_implicit_solver_alg_mod, only: semi_implicit_solver_alg_step @@ -32,18 +33,8 @@ module adjt_semi_implicit_solver_step_alg_mod use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use model_clock_mod, only: model_clock_type use function_space_mod, only: function_space_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type use field_collection_mod, only: field_collection_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg implicit none @@ -57,16 +48,18 @@ contains !> @brief Adjoint test for semi_implicit_solver_alg_mod subroutine step !> @details Does some setup, then calls the actual test via a private subroutine !! twice with different flag values - !> @param[in,out] modeldb Structure containing the model state - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine adjt_semi_implicit_solver_step_alg( modeldb, mesh, model_clock ) + !> @param[in,out] modeldb Structure containing the model state + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine adjt_semi_implicit_solver_step_alg( modeldb, mesh, model_clock, adj_lookup_table_cache ) implicit none - type(modeldb_type), target, intent(inout) :: modeldb - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(modeldb_type), target, intent(inout) :: modeldb + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_solver_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Prognostic fields type(field_type), dimension(bundle_size) :: state @@ -79,16 +72,12 @@ contains type(field_type), dimension(nummr) :: mr_in ! LS - type(field_type), dimension(bundle_size) :: ls_rdef - type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta type(field_type), pointer :: ls_exner - type(field_type), pointer :: ls_mr(:) type(field_type), pointer :: ls_moist_dyn(:) type(field_collection_type), pointer :: ls_fields type(field_collection_type), pointer :: moisture_fields - type(field_array_type), pointer :: ls_mr_array type(field_array_type), pointer :: ls_moist_dyn_array ! Variables for initialisation etc. @@ -96,12 +85,10 @@ contains type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time integer(kind=i_def) :: i + integer(kind=tik) :: id - if (subroutine_timers) call timer('adjt_semi_implicit_solver_step_alg') + if ( LPROF ) call start_timing( id, 'adjt_semi_implicit_solver_step_alg' ) ! -------------------------------------------------------------------------- ! Setup @@ -157,54 +144,19 @@ contains ! LS - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) - call ls_fields%get_field( 'ls_u', ls_u ) call ls_fields%get_field( 'ls_rho', ls_rho ) call ls_fields%get_field( 'ls_exner', ls_exner ) moisture_fields => modeldb%fields%get_field_collection("moisture_fields") - call moisture_fields%get_field( "ls_mr", ls_mr_array ) call moisture_fields%get_field( "ls_moist_dyn", ls_moist_dyn_array ) - ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u , initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - call invoke( name="adjt_siss_3", & - initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test ) ) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - call invoke( name="adjt_siss_4", & - enforce_bc_kernel_type(ls_u) ) - - call rhs(igh_u)%copy_field_properties(ls_rdef(igh_u)) - call rhs(igh_t)%copy_field_properties(ls_rdef(igh_t)) - call rhs(igh_d)%copy_field_properties(ls_rdef(igh_d)) - call rhs(igh_p)%copy_field_properties(ls_rdef(igh_p)) - - call invoke( name="adjt_siss_5", & - setval_x( ls_rdef(igh_u), ls_u ), & - setval_x( ls_rdef(igh_t), ls_theta ), & - setval_x( ls_rdef(igh_p), ls_exner ), & - setval_x( ls_rdef(igh_d), ls_rho ) ) - - ! End LS - - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & model_clock, ls_moist_dyn ) - call adj_semi_implicit_solver%initialise(rhs) + call adj_semi_implicit_solver%initialise(rhs, adj_lookup_table_cache) ! Set up moist_dyn_gas_law & mr call moist_dyn_gas_law%initialise(vector_space=vector_space_wtheta_ptr) @@ -258,7 +210,7 @@ contains call adj_semi_implicit_solver%finalise() - if (subroutine_timers) call timer('adjt_semi_implicit_solver_step_alg') + if ( LPROF ) call stop_timing( id, 'adjt_semi_implicit_solver_step_alg' ) end subroutine adjt_semi_implicit_solver_step_alg @@ -306,7 +258,6 @@ contains real(kind=r_def), parameter :: overall_tolerance = 1000.0_r_def real(kind=r_def) :: machine_tol, machine_tol_r_solver real(kind=r_def) :: relative_diff, relative_diff_r_solver - real(kind=r_def), parameter :: eps = 1e-30_r_def integer(kind=i_def) :: i @@ -362,17 +313,17 @@ contains end do ! Scaling factors are scaled up a bit to avoid numerical issues - state_sf(igh_u) = 1.0E4_r_def / (state_inner_prod(igh_u) + eps) - state_sf(igh_t) = 1.0E4_r_def / (state_inner_prod(igh_t) + eps) - state_sf(igh_d) = 1.0E4_r_def / (state_inner_prod(igh_d) + eps) - state_sf(igh_p) = 1.0E4_r_def / (state_inner_prod(igh_p) + eps) - rhs_sf(igh_u) = 1.0E4_r_def / (rhs_inner_prod(igh_u) + eps) - rhs_sf(igh_t) = 1.0E4_r_def / (rhs_inner_prod(igh_t) + eps) - rhs_sf(igh_d) = 1.0E4_r_def / (rhs_inner_prod(igh_d) + eps) - rhs_sf(igh_p) = 1.0E4_r_def / (rhs_inner_prod(igh_p) + eps) - moist_dyn_gas_law_sf = 1.0E4_r_def / (moist_dyn_gas_law_inner_prod + eps) + state_sf(igh_u) = 1.0E4_r_def / (state_inner_prod(igh_u) + EPS) + state_sf(igh_t) = 1.0E4_r_def / (state_inner_prod(igh_t) + EPS) + state_sf(igh_d) = 1.0E4_r_def / (state_inner_prod(igh_d) + EPS) + state_sf(igh_p) = 1.0E4_r_def / (state_inner_prod(igh_p) + EPS) + rhs_sf(igh_u) = 1.0E4_r_def / (rhs_inner_prod(igh_u) + EPS) + rhs_sf(igh_t) = 1.0E4_r_def / (rhs_inner_prod(igh_t) + EPS) + rhs_sf(igh_d) = 1.0E4_r_def / (rhs_inner_prod(igh_d) + EPS) + rhs_sf(igh_p) = 1.0E4_r_def / (rhs_inner_prod(igh_p) + EPS) + moist_dyn_gas_law_sf = 1.0E4_r_def / (moist_dyn_gas_law_inner_prod + EPS) do i = 1, nummr - mr_sf(i) = 1.0E4_r_def / (mr_inner_prod(i) + eps) + mr_sf(i) = 1.0E4_r_def / (mr_inner_prod(i) + EPS) end do inner1 = 0.0_r_def diff --git a/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 index d7e6cfe04..734003550 100644 --- a/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/timestepping/atlt_si_timestep_alg_mod.x90 @@ -20,17 +20,16 @@ module atlt_si_timestep_alg_mod use reference_element_mod, only: T use formulation_config_mod, only: moisture_formulation, & moisture_formulation_dry - use io_config_mod, only: subroutine_timers use derived_config_mod, only: bundle_size use fs_continuity_mod, only: Wtheta, W2, W3 - use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use field_mod, only: field_type use field_collection_mod, only: field_collection_type use mesh_mod, only: mesh_type use mr_indices_mod, only: nummr use moist_dyn_mod, only: num_moist_factors, gas_law use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use tl_si_timestep_alg_mod, only: tl_semi_implicit_alg_init, & tl_semi_implicit_alg_step, & tl_semi_implicit_alg_final @@ -38,18 +37,7 @@ module atlt_si_timestep_alg_mod use driver_modeldb_mod, only: modeldb_type use si_operators_alg_mod, only: compute_si_operators use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use initial_theta_ref_kernel_mod, only: initial_theta_ref_kernel_type - use init_gungho_prognostics_alg_mod, only: init_u_field, & - init_exner_field, & - init_rho_field, & - init_mr_fields use field_array_mod, only: field_array_type - use sci_geometric_constants_mod, only: get_coordinates, & - get_panel_id - use idealised_config_mod, only: test - use sci_field_bundle_builtins_mod, only: set_bundle_scalar - use check_configuration_mod, only: check_any_shifted - use timestepping_config_mod, only: dt implicit none @@ -81,7 +69,6 @@ contains type(field_collection_type), pointer :: derived_fields ! LS - type(field_type) :: ls_rdef(bundle_size) type(field_type), pointer :: ls_u type(field_type), pointer :: ls_rho type(field_type), pointer :: ls_theta @@ -97,9 +84,6 @@ contains type(function_space_type), pointer :: vector_space_wtheta_ptr type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - real(kind=r_def) :: initial_time integer(kind=i_def) :: i type(atl_si_timestep_type) :: atl_si_timestep @@ -115,8 +99,9 @@ contains real(kind=r_def) :: machine_tol, machine_tol_r_solver real(kind=r_def) :: relative_diff, relative_diff_r_solver real(kind=r_def), parameter :: eps = 1e-30_r_def + integer(kind=tik) :: id - if (subroutine_timers) call timer('atlt_si_timestep_alg') + if ( LPROF ) call start_timing( id, 'atlt_si_timestep_alg' ) ! -------------------------------------------------------------------------- ! Setup @@ -128,7 +113,7 @@ contains vector_space_w2_ptr => function_space_collection%get_fs( mesh, element_order_h, element_order_v, W2 ) vector_space_w3_ptr => function_space_collection%get_fs( mesh, element_order_h, element_order_v, W3 ) - ls_fields => modeldb%fields%get_field_collection("prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") call ls_fields%get_field( 'ls_theta', ls_theta ) call ls_fields%get_field( 'ls_u', ls_u ) @@ -141,34 +126,6 @@ contains ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - ! Define reference field - initial_time = 0.0_r_def - call init_u_field( ls_u, initial_time ) - call set_bundle_scalar( 0.0_r_def, ls_mr, nummr ) - - chi => get_coordinates(ls_theta%get_mesh_id()) - panel_id => get_panel_id(ls_theta%get_mesh_id()) - - call invoke(initial_theta_ref_kernel_type( ls_theta, chi, panel_id, test )) - - call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - call init_exner_field( ls_exner, ls_theta, ls_moist_dyn, initial_time ) - call init_rho_field( ls_rho, ls_theta, ls_exner, ls_moist_dyn, initial_time ) - call init_mr_fields( ls_mr, ls_theta, ls_exner, ls_rho, ls_moist_dyn ) - - call invoke( enforce_bc_kernel_type(ls_u) ) - - call ls_u%copy_field_properties(ls_rdef(igh_u)) - call ls_theta%copy_field_properties(ls_rdef(igh_t)) - call ls_rho%copy_field_properties(ls_rdef(igh_d)) - call ls_exner%copy_field_properties(ls_rdef(igh_p)) - - call invoke( setval_x(ls_rdef(igh_u), ls_u), & - setval_x(ls_rdef(igh_t), ls_theta), & - setval_x(ls_rdef(igh_p), ls_exner), & - setval_x(ls_rdef(igh_d), ls_rho) ) - ! End LS - ! Set up moist_dyn & mr do i = 1, num_moist_factors @@ -230,7 +187,7 @@ contains ls_u, ls_rho, ls_theta, ls_exner, & ls_mr, ls_moist_dyn, (num_steps == 1) ) - call compute_si_operators( ls_rdef(igh_t), ls_rdef(igh_d), ls_rdef(igh_p), & + call compute_si_operators( ls_theta, ls_rho, ls_exner, & modeldb%clock, ls_moist_dyn ) do i = 1, num_steps @@ -370,7 +327,7 @@ contains call tl_semi_implicit_alg_final() call atl_si_timestep%finalise() - if (subroutine_timers) call timer('atlt_si_timestep_alg') + if ( LPROF ) call stop_timing( id, 'atlt_si_timestep_alg' ) end subroutine atlt_si_timestep_alg diff --git a/applications/adjoint_tests/source/algorithm/transport/common/adjt_end_transport_step_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/common/adjt_end_transport_step_alg_mod.x90 index 9342ce993..7fa6bf71e 100644 --- a/applications/adjoint_tests/source/algorithm/transport/common/adjt_end_transport_step_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/common/adjt_end_transport_step_alg_mod.x90 @@ -21,7 +21,7 @@ module adjt_end_transport_step_alg_mod use model_clock_mod, only : model_clock_type use finite_element_config_mod, only : element_order_h, & element_order_v - use fs_continuity_mod, only : W2 + use fs_continuity_mod, only : W2, W2V use function_space_collection_mod, only : function_space_collection use setup_test_alg_mod, only : setup_test_tl_transport_controller use init_from_controller_alg_mod, only : init_counter_fieldvals @@ -78,6 +78,7 @@ module adjt_end_transport_step_alg_mod ! Variables for initialising fields type(function_space_type), pointer :: vector_space_w2_ptr + type(function_space_type), pointer :: vector_space_w2v_ptr ! Inner products real(kind=r_tran) :: inner1 @@ -108,13 +109,16 @@ module adjt_end_transport_step_alg_mod vector_space_w2_ptr => function_space_collection%get_fs( & mesh, element_order_h, element_order_v, W2 & - ) + ) + vector_space_w2v_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, W2V) + ! Assume that the last split step is in W2V (for VHV splitting) call sum_flux%initialise( vector_space = vector_space_w2_ptr ) - call flux_last_step%initialise( vector_space = vector_space_w2_ptr ) + call flux_last_step%initialise( vector_space = vector_space_w2v_ptr ) call sum_flux_input%initialise( vector_space = vector_space_w2_ptr ) - call flux_last_step_input%initialise( vector_space = vector_space_w2_ptr ) + call flux_last_step_input%initialise( vector_space = vector_space_w2v_ptr ) sum_flux_inner_prod = 0.0_r_def flux_last_step_inner_prod = 0.0_r_def diff --git a/applications/adjoint_tests/source/algorithm/transport/common/atlt_end_transport_step_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/common/atlt_end_transport_step_alg_mod.x90 index 08a3b7a2b..a4d64e064 100644 --- a/applications/adjoint_tests/source/algorithm/transport/common/atlt_end_transport_step_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/common/atlt_end_transport_step_alg_mod.x90 @@ -21,12 +21,14 @@ module atlt_end_transport_step_alg_mod use model_clock_mod, only : model_clock_type use finite_element_config_mod, only : element_order_h, & element_order_v - use fs_continuity_mod, only : W2, W3 + use fs_continuity_mod, only : W2, W3, W2V use function_space_collection_mod, only : function_space_collection use tl_transport_controller_mod, only : tl_transport_controller_type use transport_controller_mod, only : transport_controller_type use flux_precomputations_alg_mod, only : flux_precomputations_type use transport_counter_mod, only : transport_counter_type + use split_transport_utils_mod, only : get_num_split_steps, & + get_direction_w2_fs use setup_test_alg_mod, only : setup_test_tl_transport_controller use transport_metadata_collection_mod, only : transport_metadata_collection use transport_metadata_mod, only : transport_metadata_type @@ -233,6 +235,9 @@ module atlt_end_transport_step_alg_mod type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_mass_2_inp ! Variables for initialising fields + integer(kind=i_def) :: splitting + integer(kind=i_def) :: num_split_steps + integer(kind=i_def) :: fs_id type(function_space_type), pointer :: vector_space_w2_ptr type(function_space_type), pointer :: vector_space_w3_ptr @@ -284,11 +289,16 @@ module atlt_end_transport_step_alg_mod dummy_ref_mass_2_inp, & pert_transport_controller ) - vector_space_w2_ptr => function_space_collection%get_fs( & - mesh, element_order_h, element_order_v, W2 & + ! W2 function space appropriate for splitting (fs on the last step) + splitting = transport_metadata%get_splitting() + num_split_steps = get_num_split_steps(splitting) + fs_id = get_direction_w2_fs(splitting, num_split_steps) + vector_space_w2_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, fs_id & ) - vector_space_w3_ptr => function_space_collection%get_fs( & - mesh, element_order_h, element_order_v, W3 & + + vector_space_w3_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, W3 & ) call field_np1%initialise( vector_space = vector_space_w3_ptr ) diff --git a/applications/adjoint_tests/source/algorithm/transport/control/atlt_moist_mr_transport_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/control/atlt_moist_mr_transport_alg_mod.x90 index fe4808112..0f706f161 100644 --- a/applications/adjoint_tests/source/algorithm/transport/control/atlt_moist_mr_transport_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/control/atlt_moist_mr_transport_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for atl_moist_mr_transport_alg module atlt_moist_mr_transport_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type @@ -49,9 +50,10 @@ module atlt_moist_mr_transport_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products < Mx, Mx > and < AMx, x >, !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_moist_mr_transport_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_moist_mr_transport_alg( mesh, model_clock, adj_lookup_table_cache ) use tl_moist_mr_transport_alg_mod, only : tl_moist_mr_transport_alg use atl_moist_mr_transport_alg_mod, only : atl_moist_mr_transport_alg @@ -59,8 +61,9 @@ module atlt_moist_mr_transport_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type), dimension(:), allocatable :: mr_out @@ -202,8 +205,9 @@ module atlt_moist_mr_transport_alg_mod call wind_pc_dir_prod_rdef( inner1, pert_transport_controller, mesh_id, direction_3d ) ! Adjoint - call atl_moist_mr_transport_alg( mr_out, mr_in, ls_mr_in, & - nummr_to_transport, tl_transport_controller, transport_metadata ) + call atl_moist_mr_transport_alg( mr_out, mr_in, ls_mr_in, nummr_to_transport, & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) ! < AMx, x > inner2 = 0.0_r_def diff --git a/applications/adjoint_tests/source/algorithm/transport/control/atlt_theta_transport_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/control/atlt_theta_transport_alg_mod.x90 index 711799f0b..1b027ea72 100644 --- a/applications/adjoint_tests/source/algorithm/transport/control/atlt_theta_transport_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/control/atlt_theta_transport_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for atl_theta_transport_alg module atlt_theta_transport_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type @@ -48,9 +49,10 @@ module atlt_theta_transport_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_theta_transport_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_theta_transport_alg( mesh, model_clock, adj_lookup_table_cache ) use tl_theta_transport_alg_mod, only : tl_theta_transport_alg use atl_theta_transport_alg_mod, only : atl_theta_transport_alg @@ -58,8 +60,9 @@ module atlt_theta_transport_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: theta_out @@ -212,7 +215,8 @@ module atlt_theta_transport_alg_mod ! Adjoint call atl_theta_transport_alg( theta_out, theta_inc, theta_in, ls_theta_in, & - tl_transport_controller, transport_metadata ) + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( thout_thout_inp_inner_prod, & diff --git a/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_control_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_control_alg_mod.x90 index 93f7e94aa..3ac396cab 100644 --- a/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_control_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_control_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for atl_transport_control_alg module atlt_transport_control_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use field_mod, only : field_type use function_space_mod, only : function_space_type use constants_mod, only : r_def, i_def, l_def @@ -34,16 +35,18 @@ module atlt_transport_control_alg_mod !============================================================================= !> @brief Adjoint test for atl_transport_control_alg - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache !> - subroutine atlt_transport_control_alg( mesh, model_clock ) + subroutine atlt_transport_control_alg( mesh, model_clock, adj_lookup_table_cache ) implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Passive arguments for tl and adj calls type(field_type) :: ls_advected_fields(bundle_size) @@ -102,7 +105,8 @@ module atlt_transport_control_alg_mod ls_wind_n, & ls_mr_in, & model_clock, & - outer ) + outer, & + adj_lookup_table_cache ) end do @@ -119,6 +123,7 @@ module atlt_transport_control_alg_mod !> @param[in] ls_mr_in Linearisation state mixing ratios !> @param[in] model_clock The model clock !> @param[in] outer The outer iteration variable + !> @param[in] adj_lookup_table_cache Lookup table cache !> subroutine run_atlt_transport_control_alg( vector_space_wtheta_ptr, & vector_space_w2_ptr, & @@ -128,7 +133,8 @@ module atlt_transport_control_alg_mod ls_wind_n, & ls_mr_in, & model_clock, & - outer ) + outer, & + adj_lookup_table_cache ) use tl_transport_control_alg_mod, only : tl_transport_control_alg use atl_transport_control_alg_mod, only : atl_transport_control_alg @@ -145,6 +151,7 @@ module atlt_transport_control_alg_mod type(field_type), dimension(:), intent(in) :: ls_mr_in type(model_clock_type), intent(in) :: model_clock integer(kind=i_def), intent(in) :: outer + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Active arguments for tl and adj calls type(field_type) :: advection_inc(bundle_size) @@ -367,7 +374,7 @@ module atlt_transport_control_alg_mod wind_np1, wind_n, mr_out, mr_in, & ls_advected_fields, & ls_wind_np1, ls_wind_n, ls_mr_in, & - model_clock, outer ) + model_clock, outer, adj_lookup_table_cache ) ! < AMx, x > ai_ai_inp_inner_prod = 0.0_r_def diff --git a/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_field_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_field_alg_mod.x90 index d1120743d..182c70400 100644 --- a/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_field_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/control/atlt_transport_field_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for atl_transport_field_alg module atlt_transport_field_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type @@ -27,13 +28,19 @@ module atlt_transport_field_alg_mod use setup_test_alg_mod, only : setup_test_tl_transport_controller use inner_from_controller_rdef_alg_mod, only : flux_pc_ref_flux_prod_rdef, & flux_pc_ref_flux_inp_prod_rdef, & + counter_flux_prod_rdef, & + counter_flux_inp_prod_rdef, & + counter_field_n_prod_rdef, & + counter_field_n_inp_prod_rdef, & wind_pc_dir_prod_rdef, & wind_pc_dir_inp_prod_rdef use init_from_controller_alg_mod, only : init_flux_pc_fieldvals, & - init_wind_pc_fieldvals + init_wind_pc_fieldvals, & + init_counter_fieldvals use transport_enumerated_types_mod, only : direction_3d, & direction_h, & direction_v + use fs_continuity_mod, only : W3 implicit none @@ -47,9 +54,10 @@ module atlt_transport_field_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_transport_field_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_transport_field_alg( mesh, model_clock, adj_lookup_table_cache ) use tl_transport_field_mod, only : tl_transport_field use atl_transport_field_mod, only : atl_transport_field @@ -57,8 +65,9 @@ module atlt_transport_field_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: field_np1 @@ -86,18 +95,25 @@ module atlt_transport_field_alg_mod ! Variables used to handle calculations for fields stored in tl_transport_controller integer(kind=i_def) :: mesh_id + type(transport_controller_type), pointer :: transport_controller type(transport_controller_type), pointer :: pert_transport_controller type(transport_controller_type), pointer :: ls_transport_controller type(transport_metadata_type), pointer :: transport_metadata type(r_tran_field_type), dimension(:), allocatable :: fpc_ls_wind_ref_flux_inp + type(r_tran_field_type), dimension(:), allocatable :: fpc_ls_wind_ref_flux_inp2 type(r_tran_field_type), dimension(:), allocatable :: fpc_pert_wind_ref_flux_inp type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_field_1_inp type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_mass_1_inp type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_field_2_inp type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_mass_2_inp + type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_field_3_inp + type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_mass_3_inp type(r_tran_field_type) :: wind_pc_h_inp type(r_tran_field_type) :: wind_pc_v_inp type(r_tran_field_type) :: wind_pc_3d_inp + type(r_tran_field_type) :: tctr_field_n_inp + type(r_tran_field_type), dimension(:), allocatable :: tctr_flux_inp + type(function_space_type), pointer :: vector_space_w3_ptr ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -106,11 +122,16 @@ module atlt_transport_field_alg_mod mesh_id = mesh%get_id() call setup_test_tl_transport_controller( mesh, model_clock, tl_transport_controller, field_n, field_n_fs ) + transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() ls_transport_controller => tl_transport_controller%get_ls_wind_pert_rho_controller() pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() transport_metadata => pert_transport_controller%get_transport_metadata() ! Initialising fields + call init_counter_fieldvals( mesh, & + tctr_field_n_inp, & + tctr_flux_inp, & + pert_transport_controller ) call init_flux_pc_fieldvals( mesh, & 1_i_def, & fpc_ls_wind_ref_flux_inp, & @@ -123,6 +144,12 @@ module atlt_transport_field_alg_mod dummy_ref_field_2_inp, & dummy_ref_mass_2_inp, & pert_transport_controller ) + call init_flux_pc_fieldvals( mesh, & + 1_i_def, & + fpc_ls_wind_ref_flux_inp2, & + dummy_ref_field_3_inp, & + dummy_ref_mass_3_inp, & + transport_controller ) call init_wind_pc_fieldvals( mesh, & wind_pc_h_inp, & direction_h, & @@ -136,6 +163,11 @@ module atlt_transport_field_alg_mod direction_3d, & pert_transport_controller ) + vector_space_w3_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, W3 & + ) + call field_n%initialise(vector_space = vector_space_w3_ptr) + call field_n%copy_field_properties( field_np1 ) call field_n%copy_field_properties( ls_field_n ) @@ -147,6 +179,7 @@ module atlt_transport_field_alg_mod ! Initialise values and call the tangent-linear alg. call invoke( setval_random( field_np1 ), & + setval_random( field_n ), & setval_x( field_np1_input, field_np1 ), & setval_x( field_n_input, field_n ), & setval_random( ls_field_n ) ) @@ -179,6 +212,7 @@ module atlt_transport_field_alg_mod call wind_pc_dir_prod_rdef( inner1, pert_transport_controller, mesh_id, direction_h ) call wind_pc_dir_prod_rdef( inner1, pert_transport_controller, mesh_id, direction_v ) call wind_pc_dir_prod_rdef( inner1, pert_transport_controller, mesh_id, direction_3d ) + call counter_flux_prod_rdef( inner1, pert_transport_controller ) ! Scaling fields call invoke( inc_a_times_X( field_np1_sf, field_np1 ), & @@ -191,7 +225,8 @@ module atlt_transport_field_alg_mod ! Adjoint call atl_transport_field( & field_np1, field_n, ls_field_n, & - tl_transport_controller, transport_metadata & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache & ) ! < AMx, x > @@ -210,6 +245,7 @@ module atlt_transport_field_alg_mod call wind_pc_dir_inp_prod_rdef( inner2, pert_transport_controller, mesh_id, direction_h, wind_pc_h_inp ) call wind_pc_dir_inp_prod_rdef( inner2, pert_transport_controller, mesh_id, direction_v, wind_pc_v_inp ) call wind_pc_dir_inp_prod_rdef( inner2, pert_transport_controller, mesh_id, direction_3d, wind_pc_3d_inp ) + call counter_flux_inp_prod_rdef( inner2, pert_transport_controller, tctr_flux_inp ) call tl_transport_controller%finalise() if ( allocated(fpc_ls_wind_ref_flux_inp) ) deallocate( fpc_ls_wind_ref_flux_inp ) diff --git a/applications/adjoint_tests/source/algorithm/transport/control/atlt_wind_transport_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/control/atlt_wind_transport_alg_mod.x90 index 8fd27ff48..480c73a96 100644 --- a/applications/adjoint_tests/source/algorithm/transport/control/atlt_wind_transport_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/control/atlt_wind_transport_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for atl_wind_transport_alg module atlt_wind_transport_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type @@ -48,9 +49,10 @@ module atlt_wind_transport_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_wind_transport_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_wind_transport_alg( mesh, model_clock, adj_lookup_table_cache ) use tl_wind_transport_alg_mod, only : tl_wind_transport_alg use atl_wind_transport_alg_mod, only : atl_wind_transport_alg @@ -58,8 +60,9 @@ module atlt_wind_transport_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: rhs_u @@ -194,8 +197,9 @@ module atlt_wind_transport_alg_mod wn_wn_inp_inner_prod = 0.0_r_def ! Adjoint - call atl_wind_transport_alg( rhs_u, wind_n, ls_wind_n, & - tl_transport_controller, transport_metadata ) + call atl_wind_transport_alg( rhs_u, wind_n, ls_wind_n, & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( ru_ru_inp_inner_prod, & diff --git a/applications/adjoint_tests/source/algorithm/transport/init_from_controller_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/init_from_controller_alg_mod.x90 index 17e300fa3..d33548660 100644 --- a/applications/adjoint_tests/source/algorithm/transport/init_from_controller_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/init_from_controller_alg_mod.x90 @@ -222,7 +222,9 @@ module init_from_controller_alg_mod if ( flux_ptr%is_initialised() ) then call invoke( setval_X( counter_flux_inp(step), flux_ptr ) ) else - call invoke( setval_c( counter_flux_inp(step), 0.0_r_tran ) ) + call counter_flux_inp(step)%copy_field_properties(flux_ptr) + call invoke( setval_random( flux_ptr ), & + setval_X( counter_flux_inp(step), flux_ptr ) ) end if end do diff --git a/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rdef_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rdef_alg_mod.x90 index d98491647..bef3c3a70 100644 --- a/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rdef_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rdef_alg_mod.x90 @@ -8,7 +8,7 @@ module inner_from_controller_rdef_alg_mod - use constants_mod, only : i_def, l_def, r_def + use constants_mod, only : i_def, l_def, r_def, EPS use field_mod, only : field_type use r_tran_field_mod, only : r_tran_field_type use transport_controller_mod, only : transport_controller_type @@ -72,7 +72,6 @@ module inner_from_controller_rdef_alg_mod type(flux_precomputations_type), pointer :: flux_pc type(r_tran_field_type), pointer :: ref_flux_ptr real(kind=r_def) :: flux_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def integer(kind=i_def) :: step integer(kind=i_def) :: num_steps integer(kind=i_def) :: mesh_id_from_idx @@ -88,7 +87,7 @@ module inner_from_controller_rdef_alg_mod flux_inner_prod = 0.0_r_def if ( ref_flux_ptr%is_initialised() ) then call invoke( x_innerproduct_x( flux_inner_prod, ref_flux_ptr ) ) - flux_sf = 1.0_r_def/(flux_inner_prod + eps) + flux_sf = 1.0_r_def/(flux_inner_prod + EPS) inner = inner + flux_inner_prod*flux_sf write(log_scratch_space, *) "Flux precomputations ref_flux(step = ", step, ") inner prod = ", & flux_inner_prod @@ -164,7 +163,6 @@ module inner_from_controller_rdef_alg_mod type(flux_precomputations_type), pointer :: flux_pc type(r_tran_field_type), pointer :: ref_field_ptr real(kind=r_def) :: field_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def integer(kind=i_def) :: step integer(kind=i_def) :: num_steps integer(kind=i_def) :: mesh_id_from_idx @@ -181,7 +179,7 @@ module inner_from_controller_rdef_alg_mod field_inner_prod = 0.0_r_def if ( ref_field_ptr%is_initialised() ) then call invoke( x_innerproduct_x( field_inner_prod, ref_field_ptr ) ) - field_sf = 1.0_r_def/(field_inner_prod + eps) + field_sf = 1.0_r_def/(field_inner_prod + EPS) inner = inner + field_inner_prod*field_sf write(log_scratch_space, *) "Flux precomputations ref_field(step = ", step, ") inner prod = ", & field_inner_prod @@ -256,7 +254,6 @@ module inner_from_controller_rdef_alg_mod type(flux_precomputations_type), pointer :: flux_pc type(r_tran_field_type), pointer :: ref_mass_ptr real(kind=r_def) :: mass_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def integer(kind=i_def) :: step integer(kind=i_def) :: num_steps integer(kind=i_def) :: mesh_id_from_idx @@ -273,7 +270,7 @@ module inner_from_controller_rdef_alg_mod mass_inner_prod = 0.0_r_def if ( ref_mass_ptr%is_initialised() ) then call invoke( x_innerproduct_x( mass_inner_prod, ref_mass_ptr ) ) - mass_sf = 1.0_r_def/(mass_inner_prod + eps) + mass_sf = 1.0_r_def/(mass_inner_prod + EPS) inner = inner + mass_inner_prod*mass_sf write(log_scratch_space, *) "Flux precomputations ref_mass(step = ", step, ") inner prod = ", & mass_inner_prod @@ -345,7 +342,6 @@ module inner_from_controller_rdef_alg_mod type(transport_counter_type), pointer :: transport_counter type(r_tran_field_type), pointer :: flux_ptr real(kind=r_def) :: flux_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def integer(kind=i_def) :: step integer(kind=i_def) :: num_steps real(kind=r_def) :: flux_inner_prod @@ -358,7 +354,7 @@ module inner_from_controller_rdef_alg_mod flux_inner_prod = 0.0_r_def if ( flux_ptr%is_initialised() ) then call invoke( x_innerproduct_x( flux_inner_prod, flux_ptr ) ) - flux_sf = 1.0_r_def/(flux_inner_prod + eps) + flux_sf = 1.0_r_def/(flux_inner_prod + EPS) inner = inner + flux_inner_prod*flux_sf write(log_scratch_space, *) "Transport counter flux(step = ", step, ") inner prod = ", & flux_inner_prod @@ -425,7 +421,6 @@ module inner_from_controller_rdef_alg_mod type(transport_counter_type), pointer :: transport_counter type(r_tran_field_type), pointer :: field_n_ptr real(kind=r_def) :: field_n_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def real(kind=r_def) :: field_n_inner_prod transport_counter => transport_controller%get_transport_counter() @@ -434,7 +429,7 @@ module inner_from_controller_rdef_alg_mod if ( field_n_ptr%is_initialised() ) then field_n_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( field_n_inner_prod, field_n_ptr ) ) - field_n_sf = 1.0_r_def/(field_n_inner_prod + eps) + field_n_sf = 1.0_r_def/(field_n_inner_prod + EPS) inner = inner + field_n_inner_prod*field_n_sf write(log_scratch_space, *) "Transport counter field_n inner prod = ", & field_n_inner_prod @@ -499,7 +494,6 @@ module inner_from_controller_rdef_alg_mod type(wind_precomputations_type), pointer :: wind_pc type(r_tran_field_type), pointer :: wind_ptr real(kind=r_def) :: wind_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def real(kind=r_def) :: wind_inner_prod wind_pc => transport_controller%get_wind_precomputations() @@ -508,7 +502,7 @@ module inner_from_controller_rdef_alg_mod if ( wind_ptr%is_initialised() ) then wind_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( wind_inner_prod, wind_ptr ) ) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner = inner + wind_inner_prod*wind_sf write(log_scratch_space, *) "Wind precomputations(delta_t = ", delta_t, ") inner prod = ", & wind_inner_prod @@ -579,7 +573,6 @@ module inner_from_controller_rdef_alg_mod type(wind_precomputations_type), pointer :: wind_pc type(r_tran_field_type), pointer :: wind_ptr real(kind=r_def) :: wind_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def real(kind=r_def) :: wind_inner_prod wind_pc => transport_controller%get_wind_precomputations() @@ -588,7 +581,7 @@ module inner_from_controller_rdef_alg_mod if ( wind_ptr%is_initialised() ) then wind_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( wind_inner_prod, wind_ptr ) ) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner = inner + wind_inner_prod*wind_sf write(log_scratch_space, *) "Wind precomputations(direction = ", direction, ") inner prod = ", & wind_inner_prod @@ -652,7 +645,6 @@ module inner_from_controller_rdef_alg_mod ! Internal variables type(r_tran_field_type), pointer :: ref_field_ptr real(kind=r_def) :: ref_field_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def real(kind=r_def) :: ref_field_inner_prod ref_field_ptr => transport_controller%get_ref_field() @@ -660,7 +652,7 @@ module inner_from_controller_rdef_alg_mod if ( ref_field_ptr%is_initialised() ) then ref_field_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( ref_field_inner_prod, ref_field_ptr ) ) - ref_field_sf = 1.0_r_def/(ref_field_inner_prod + eps) + ref_field_sf = 1.0_r_def/(ref_field_inner_prod + EPS) inner = inner + ref_field_inner_prod*ref_field_sf write(log_scratch_space, *) "Transport controller ref_field inner prod = ", & ref_field_inner_prod @@ -719,7 +711,6 @@ module inner_from_controller_rdef_alg_mod ! Internal variables type(r_tran_field_type), pointer :: wind_ptr real(kind=r_def) :: wind_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def real(kind=r_def) :: wind_inner_prod wind_ptr => transport_controller%get_wind_npdt( delta_t ) @@ -727,7 +718,7 @@ module inner_from_controller_rdef_alg_mod if ( wind_ptr%is_initialised() ) then wind_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( wind_inner_prod, wind_ptr ) ) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner = inner + wind_inner_prod*wind_sf write(log_scratch_space, *) "Transport controller wind(delta_t = ", delta_t, ") inner prod = ", & wind_inner_prod @@ -786,7 +777,6 @@ module inner_from_controller_rdef_alg_mod ! Internal variables type(r_tran_field_type), pointer :: wind_ptr real(kind=r_def) :: wind_sf - real(kind=r_def), parameter :: eps = 1.0e-30_r_def real(kind=r_def) :: wind_inner_prod wind_ptr => transport_controller%get_transporting_wind() @@ -794,7 +784,7 @@ module inner_from_controller_rdef_alg_mod if ( wind_ptr%is_initialised() ) then wind_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( wind_inner_prod, wind_ptr ) ) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner = inner + wind_inner_prod*wind_sf write(log_scratch_space, *) "Transport controller transporting_wind inner prod = ", & wind_inner_prod diff --git a/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rtran_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rtran_alg_mod.x90 index 4a56dd02e..2ee21745e 100644 --- a/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rtran_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/inner_from_controller_rtran_alg_mod.x90 @@ -8,7 +8,8 @@ module inner_from_controller_rtran_alg_mod - use constants_mod, only : i_def, l_def, r_def, r_tran + use constants_mod, only : i_def, l_def, r_def, & + r_tran, EPS use r_tran_field_mod, only : r_tran_field_type use transport_controller_mod, only : transport_controller_type use flux_precomputations_alg_mod, only : flux_precomputations_type @@ -62,7 +63,6 @@ module inner_from_controller_rtran_alg_mod type(flux_precomputations_type), pointer :: flux_pc type(r_tran_field_type), pointer :: ref_flux_ptr real(kind=r_tran) :: flux_sf - real(kind=r_tran), parameter :: eps = 1.0e-30_r_tran integer(kind=i_def) :: step integer(kind=i_def) :: num_steps integer(kind=i_def) :: mesh_id_from_idx @@ -79,7 +79,7 @@ module inner_from_controller_rtran_alg_mod flux_inner_prod = 0.0_r_def if ( ref_flux_ptr%is_initialised() ) then call invoke( x_innerproduct_x( flux_inner_prod, ref_flux_ptr ) ) - flux_sf = 1.0_r_tran/( real(flux_inner_prod, r_tran) + eps ) + flux_sf = 1.0_r_tran/( real(flux_inner_prod, r_tran) + EPS ) inner = inner + real( flux_inner_prod, r_tran )*flux_sf write(log_scratch_space, *) "Flux precomputations ref_flux(step = ", step, ") inner prod = ", & real( flux_inner_prod, r_tran ) @@ -154,7 +154,6 @@ module inner_from_controller_rtran_alg_mod type(flux_precomputations_type), pointer :: flux_pc type(r_tran_field_type), pointer :: ref_field_ptr real(kind=r_tran) :: field_sf - real(kind=r_tran), parameter :: eps = 1.0e-30_r_tran integer(kind=i_def) :: step integer(kind=i_def) :: num_steps integer(kind=i_def) :: mesh_id_from_idx @@ -171,7 +170,7 @@ module inner_from_controller_rtran_alg_mod field_inner_prod = 0.0_r_def if ( ref_field_ptr%is_initialised() ) then call invoke( x_innerproduct_x( field_inner_prod, ref_field_ptr ) ) - field_sf = 1.0_r_tran/( real( field_inner_prod, r_tran ) + eps ) + field_sf = 1.0_r_tran/( real( field_inner_prod, r_tran ) + EPS ) inner = inner + real( field_inner_prod, r_tran )*field_sf write(log_scratch_space, *) "Flux precomputations ref_field(step = ", step, ") inner prod = ", & real( field_inner_prod, r_tran ) @@ -246,7 +245,6 @@ module inner_from_controller_rtran_alg_mod type(flux_precomputations_type), pointer :: flux_pc type(r_tran_field_type), pointer :: ref_mass_ptr real(kind=r_tran) :: mass_sf - real(kind=r_tran), parameter :: eps = 1.0e-30_r_tran integer(kind=i_def) :: step integer(kind=i_def) :: num_steps integer(kind=i_def) :: mesh_id_from_idx @@ -263,7 +261,7 @@ module inner_from_controller_rtran_alg_mod mass_inner_prod = 0.0_r_def if ( ref_mass_ptr%is_initialised() ) then call invoke( x_innerproduct_x( mass_inner_prod, ref_mass_ptr ) ) - mass_sf = 1.0_r_tran/( real( mass_inner_prod, r_tran ) + eps ) + mass_sf = 1.0_r_tran/( real( mass_inner_prod, r_tran ) + EPS ) inner = inner + real( mass_inner_prod, r_tran )*mass_sf write(log_scratch_space, *) "Flux precomputations ref_mass(step = ", step, ") inner prod = ", & real( mass_inner_prod, r_tran ) @@ -335,7 +333,6 @@ module inner_from_controller_rtran_alg_mod type(transport_counter_type), pointer :: transport_counter type(r_tran_field_type), pointer :: flux_ptr real(kind=r_tran) :: flux_sf - real(kind=r_tran), parameter :: eps = 1.0e-30_r_tran integer(kind=i_def) :: step integer(kind=i_def) :: num_steps real(kind=r_def) :: flux_inner_prod @@ -348,7 +345,7 @@ module inner_from_controller_rtran_alg_mod flux_inner_prod = 0.0_r_def if ( flux_ptr%is_initialised() ) then call invoke( x_innerproduct_x( flux_inner_prod, flux_ptr ) ) - flux_sf = 1.0_r_tran/( real( flux_inner_prod, r_tran ) + eps ) + flux_sf = 1.0_r_tran/( real( flux_inner_prod, r_tran ) + EPS ) inner = inner + real( flux_inner_prod, r_tran )*flux_sf write(log_scratch_space, *) "Transport counter flux(step = ", step, ") inner prod = ", & real( flux_inner_prod, r_tran ) @@ -413,7 +410,6 @@ module inner_from_controller_rtran_alg_mod type(transport_counter_type), pointer :: transport_counter type(r_tran_field_type), pointer :: field_n_ptr real(kind=r_tran) :: field_n_sf - real(kind=r_tran), parameter :: eps = 1.0e-30_r_tran real(kind=r_def) :: field_n_inner_prod transport_counter => transport_controller%get_transport_counter() @@ -422,7 +418,7 @@ module inner_from_controller_rtran_alg_mod if ( field_n_ptr%is_initialised() ) then field_n_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( field_n_inner_prod, field_n_ptr ) ) - field_n_sf = 1.0_r_tran/( real( field_n_inner_prod, r_tran ) + eps ) + field_n_sf = 1.0_r_tran/( real( field_n_inner_prod, r_tran ) + EPS ) inner = inner + real( field_n_inner_prod, r_tran )*field_n_sf write(log_scratch_space, *) "Transport counter field_n inner prod = ", & real( field_n_inner_prod, r_tran ) @@ -487,7 +483,6 @@ module inner_from_controller_rtran_alg_mod type(wind_precomputations_type), pointer :: wind_pc type(r_tran_field_type), pointer :: wind_ptr real(kind=r_tran) :: wind_sf - real(kind=r_tran), parameter :: eps = 1.0e-30_r_tran real(kind=r_def) :: wind_inner_prod wind_pc => transport_controller%get_wind_precomputations() @@ -496,7 +491,7 @@ module inner_from_controller_rtran_alg_mod if ( wind_ptr%is_initialised() ) then wind_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( wind_inner_prod, wind_ptr ) ) - wind_sf = 1.0_r_tran/( real( wind_inner_prod, r_tran ) + eps ) + wind_sf = 1.0_r_tran/( real( wind_inner_prod, r_tran ) + EPS ) inner = inner + real( wind_inner_prod, r_tran )*wind_sf write(log_scratch_space, *) "Wind precomputations(delta_t = ", delta_t, ") inner prod = ", & real( wind_inner_prod, r_tran ) @@ -567,7 +562,6 @@ module inner_from_controller_rtran_alg_mod type(wind_precomputations_type), pointer :: wind_pc type(r_tran_field_type), pointer :: wind_ptr real(kind=r_tran) :: wind_sf - real(kind=r_tran), parameter :: eps = 1.0e-30_r_tran real(kind=r_def) :: wind_inner_prod wind_pc => transport_controller%get_wind_precomputations() @@ -576,7 +570,7 @@ module inner_from_controller_rtran_alg_mod if ( wind_ptr%is_initialised() ) then wind_inner_prod = 0.0_r_def call invoke( x_innerproduct_x( wind_inner_prod, wind_ptr ) ) - wind_sf = 1.0_r_tran/( real( wind_inner_prod, r_tran ) + eps ) + wind_sf = 1.0_r_tran/( real( wind_inner_prod, r_tran ) + EPS ) inner = inner + real( wind_inner_prod, r_tran )*wind_sf write(log_scratch_space, *) "Wind precomputations(direction = ", direction, ") inner prod = ", & real( wind_inner_prod, r_tran ) diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/adjt_reconstruct_w3_field_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/mol/adjt_reconstruct_w3_field_alg_mod.x90 index 0ccda5295..164b3d534 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/adjt_reconstruct_w3_field_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/adjt_reconstruct_w3_field_alg_mod.x90 @@ -6,9 +6,10 @@ !> @brief Module containing adjoint test for adj_reconstruct_w3_field_alg module adjt_reconstruct_w3_field_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use field_mod, only : field_type use function_space_mod, only : function_space_type - use constants_mod, only : r_def, i_def, l_def + use constants_mod, only : r_def, i_def, l_def, EPS use log_mod, only : log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -22,7 +23,6 @@ module adjt_reconstruct_w3_field_alg_mod use function_space_collection_mod, only : function_space_collection use transport_metadata_collection_mod, only : transport_metadata_collection use transport_metadata_mod, only : transport_metadata_type - use check_configuration_mod, only : get_required_stencil_depth implicit none @@ -36,9 +36,10 @@ module adjt_reconstruct_w3_field_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine adjt_hori_w3_reconstruct_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine adjt_hori_w3_reconstruct_alg( mesh, model_clock, adj_lookup_table_cache ) use adj_reconstruct_w3_field_alg_mod, only : adj_hori_w3_reconstruct_alg use reconstruct_w3_field_alg_mod, only : hori_w3_reconstruct_alg @@ -46,8 +47,9 @@ module adjt_reconstruct_w3_field_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: field_new @@ -72,7 +74,6 @@ module adjt_reconstruct_w3_field_alg_mod real(kind=r_def) :: inner2 real(kind=r_def) :: field_new_field_new_input_inner_prod real(kind=r_def) :: field_old_field_old_input_inner_prod - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -112,8 +113,8 @@ module adjt_reconstruct_w3_field_alg_mod x_innerproduct_x( field_old_inner_prod, field_old ) ) ! Determining scale factors - field_new_sf = 1.0_r_def/(field_new_inner_prod + eps) - field_old_sf = 1.0_r_def/(field_old_inner_prod + eps) + field_new_sf = 1.0_r_def/(field_new_inner_prod + EPS) + field_old_sf = 1.0_r_def/(field_old_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + field_new_inner_prod*field_new_sf @@ -135,7 +136,8 @@ module adjt_reconstruct_w3_field_alg_mod ! Adjoint call adj_hori_w3_reconstruct_alg( field_new, field_old, & - transport_metadata ) + transport_metadata, & + adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( field_new_field_new_input_inner_prod, & diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/adjt_wt_advective_update_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/mol/adjt_wt_advective_update_alg_mod.x90 index 6c20ece3d..0eb5cc146 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/adjt_wt_advective_update_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/adjt_wt_advective_update_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing adjoint test for adj_wt_advective_update_alg module adjt_wt_advective_update_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use field_mod, only : field_type use function_space_mod, only : function_space_type use mesh_mod, only : mesh_type @@ -14,7 +15,7 @@ module adjt_wt_advective_update_alg_mod use finite_element_config_mod, only : element_order_h, & element_order_v use fs_continuity_mod, only : W2h, W2v, Wtheta - use constants_mod, only : i_def, r_def, l_def + use constants_mod, only : i_def, r_def, l_def, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -35,9 +36,10 @@ module adjt_wt_advective_update_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine adjt_hori_wt_update_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine adjt_hori_wt_update_alg( mesh, model_clock, adj_lookup_table_cache ) use wt_advective_update_alg_mod, only : hori_wt_update_alg use adj_wt_advective_update_alg_mod, only : adj_hori_wt_update_alg @@ -45,8 +47,9 @@ module adjt_wt_advective_update_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal arguments for forward and adjoint type(field_type) :: u_grad_f @@ -72,7 +75,6 @@ module adjt_wt_advective_update_alg_mod real(kind=r_def) :: advective_advective_input_inner_prod real(kind=r_def) :: field_field_input_inner_prod real(kind=r_def) :: inner2 - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -107,8 +109,8 @@ module adjt_wt_advective_update_alg_mod x_innerproduct_x(field_inner_prod, field) ) ! Determining scale factors - advective_sf = 1.0_r_def/(advective_inner_prod + eps) - field_sf = 1.0_r_def/(field_inner_prod + eps) + advective_sf = 1.0_r_def/(advective_inner_prod + EPS) + field_sf = 1.0_r_def/(field_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + advective_inner_prod*advective_sf @@ -127,7 +129,7 @@ module adjt_wt_advective_update_alg_mod advective_advective_input_inner_prod = 0.0_r_def field_field_input_inner_prod = 0.0_r_def - call adj_hori_wt_update_alg( u_grad_f, ls_wind, ls_wind, field, transport_metadata ) + call adj_hori_wt_update_alg( u_grad_f, ls_wind, ls_wind, field, transport_metadata, adj_lookup_table_cache ) call invoke( x_innerproduct_y(advective_advective_input_inner_prod, u_grad_f, advective_input), & x_innerproduct_y(field_field_input_inner_prod, field, field_input) ) diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_advective_and_flux_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_advective_and_flux_alg_mod.x90 index e12aa59a9..6082fa336 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_advective_and_flux_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_advective_and_flux_alg_mod.x90 @@ -6,10 +6,11 @@ !> @brief Module containing adjoint test for atl_advective_and_flux_alg module atlt_advective_and_flux_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type - use constants_mod, only : r_def, i_def, l_def + use constants_mod, only : r_def, i_def, l_def, EPS use log_mod, only : log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -37,9 +38,10 @@ module atlt_advective_and_flux_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_advective_and_flux_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_advective_and_flux_alg( mesh, model_clock, adj_lookup_table_cache ) use atl_advective_and_flux_alg_mod, only : atl_advective_and_flux_alg use tl_advective_and_flux_alg_mod, only : tl_advective_and_flux_alg @@ -47,8 +49,9 @@ module atlt_advective_and_flux_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: mass_flux_1 @@ -94,7 +97,6 @@ module atlt_advective_and_flux_alg_mod real(kind=r_def) :: adv_inc_adv_inc_input_inner_prod real(kind=r_def) :: density_density_input_inner_prod real(kind=r_def) :: wind_wind_input_inner_prod - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -173,11 +175,11 @@ module atlt_advective_and_flux_alg_mod x_innerproduct_x( wind_inner_prod, wind ) ) ! Determining scale factors - mass_flux_1_sf = 1.0_r_def/(mass_flux_1_inner_prod + eps) - mass_flux_2_sf = 1.0_r_def/(mass_flux_2_inner_prod + eps) - adv_inc_sf = 1.0_r_def/(adv_inc_inner_prod + eps) - density_sf = 1.0_r_def/(density_inner_prod + eps) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + mass_flux_1_sf = 1.0_r_def/(mass_flux_1_inner_prod + EPS) + mass_flux_2_sf = 1.0_r_def/(mass_flux_2_inner_prod + EPS) + adv_inc_sf = 1.0_r_def/(adv_inc_inner_prod + EPS) + density_sf = 1.0_r_def/(density_inner_prod + EPS) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + mass_flux_1_inner_prod*mass_flux_1_sf @@ -217,7 +219,8 @@ module atlt_advective_and_flux_alg_mod density, wind, ls_density, ls_wind, & direction, transport_metadata, & final_rk_stage, dt, & - do_flux, do_advective ) + do_flux, do_advective, & + adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( mass_flux_1_mass_flux_1_input_inner_prod, & diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_advective_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_advective_alg_mod.x90 index 92fd13b5a..020220d98 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_advective_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_advective_alg_mod.x90 @@ -6,10 +6,11 @@ !> @brief Module containing adjoint test for atl_mol_advective_alg module atlt_mol_advective_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type - use constants_mod, only : r_def, i_def, l_def + use constants_mod, only : r_def, i_def, l_def, EPS use log_mod, only : log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -46,9 +47,10 @@ module atlt_mol_advective_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_mol_advective_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_mol_advective_alg( mesh, model_clock, adj_lookup_table_cache ) use atl_mol_advective_alg_mod, only : atl_mol_advective_alg use tl_mol_advective_alg_mod, only : tl_mol_advective_alg @@ -56,8 +58,9 @@ module atlt_mol_advective_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: field_np1 @@ -81,7 +84,6 @@ module atlt_mol_advective_alg_mod real(kind=r_def) :: inner2 real(kind=r_def) :: field_np1_field_np1_input_inner_prod real(kind=r_def) :: field_field_input_inner_prod - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Variables used to handle calculations for fields stored in tl_transport_controller integer(kind=i_def) :: mesh_id @@ -144,8 +146,8 @@ module atlt_mol_advective_alg_mod x_innerproduct_x( field_inner_prod, field ) ) ! Determining scale factors - field_np1_sf = 1.0_r_def/(field_np1_inner_prod + eps) - field_sf = 1.0_r_def/(field_inner_prod + eps) + field_np1_sf = 1.0_r_def/(field_np1_inner_prod + EPS) + field_sf = 1.0_r_def/(field_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + field_np1_inner_prod*field_np1_sf @@ -169,7 +171,7 @@ module atlt_mol_advective_alg_mod field_field_input_inner_prod = 0.0_r_def ! Adjoint - call atl_mol_advective_alg( field_np1, field, ls_field, tl_transport_controller ) + call atl_mol_advective_alg( field_np1, field, ls_field, tl_transport_controller, adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( field_np1_field_np1_input_inner_prod, & diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_conservative_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_conservative_alg_mod.x90 index 6f2a2cabc..2b5d89620 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_conservative_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_mol_conservative_alg_mod.x90 @@ -6,10 +6,11 @@ !> @brief Module containing adjoint test for atl_mol_conservative_alg module atlt_mol_conservative_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type - use constants_mod, only : r_def, i_def, l_def + use constants_mod, only : r_def, i_def, l_def, EPS use copy_field_alg_mod, only : copy_field use log_mod, only : log_event, & log_scratch_space, & @@ -56,9 +57,10 @@ module atlt_mol_conservative_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_mol_conservative_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_mol_conservative_alg( mesh, model_clock, adj_lookup_table_cache ) use atl_mol_conservative_alg_mod, only : atl_mol_conservative_alg use tl_mol_conservative_alg_mod, only : tl_mol_conservative_alg @@ -66,8 +68,9 @@ module atlt_mol_conservative_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: field_np1 @@ -91,22 +94,25 @@ module atlt_mol_conservative_alg_mod real(kind=r_def) :: inner2 real(kind=r_def) :: field_np1_field_np1_input_inner_prod real(kind=r_def) :: field_field_input_inner_prod - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Variables used to handle calculations for fields stored in tl_transport_controller integer(kind=i_def) :: mesh_id type(transport_controller_type), pointer :: pert_transport_controller type(transport_controller_type), pointer :: ls_transport_controller + type(transport_controller_type), pointer :: transport_controller type(field_type) :: tctr_field_n type(function_space_type), pointer :: tctr_field_n_vs type(field_type) :: tctr_field_n_inp type(r_tran_field_type), dimension(:), allocatable :: tctr_flux_inp type(r_tran_field_type), dimension(:), allocatable :: fpc_ls_wind_ref_flux_inp type(r_tran_field_type), dimension(:), allocatable :: fpc_pert_wind_ref_flux_inp + type(r_tran_field_type), dimension(:), allocatable :: fpc_ls_wind_ref_flux_inp2 type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_field_1_inp type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_mass_1_inp type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_field_2_inp type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_mass_2_inp + type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_field_3_inp + type(r_tran_field_type), dimension(:), allocatable :: dummy_ref_mass_3_inp type(r_tran_field_type) :: wind_pc_h_inp type(r_tran_field_type) :: wind_pc_v_inp type(r_tran_field_type) :: wind_pc_3d_inp @@ -118,6 +124,7 @@ module atlt_mol_conservative_alg_mod mesh_id = mesh%get_id() call setup_test_tl_transport_controller( mesh, model_clock, tl_transport_controller, tctr_field_n, tctr_field_n_vs ) + transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() ls_transport_controller => tl_transport_controller%get_ls_wind_pert_rho_controller() pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() @@ -126,6 +133,12 @@ module atlt_mol_conservative_alg_mod tctr_field_n_inp, & tctr_flux_inp, & pert_transport_controller ) + call init_flux_pc_fieldvals( mesh, & + 1_i_def, & + fpc_ls_wind_ref_flux_inp2, & + dummy_ref_field_3_inp, & + dummy_ref_mass_3_inp, & + transport_controller ) call init_flux_pc_fieldvals( mesh, & 1_i_def, & fpc_ls_wind_ref_flux_inp, & @@ -182,8 +195,8 @@ module atlt_mol_conservative_alg_mod x_innerproduct_x( field_inner_prod, field ) ) ! Determining scale factors - field_np1_sf = 1.0_r_def/(field_np1_inner_prod + eps) - field_sf = 1.0_r_def/(field_inner_prod + eps) + field_np1_sf = 1.0_r_def/(field_np1_inner_prod + EPS) + field_sf = 1.0_r_def/(field_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + field_np1_inner_prod*field_np1_sf @@ -212,7 +225,8 @@ module atlt_mol_conservative_alg_mod ! Adjoint call atl_mol_conservative_alg( field_np1, field, ls_field, & - tl_transport_controller ) + tl_transport_controller, & + adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( field_np1_field_np1_input_inner_prod, & diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly1d_vert_w3_recon_alg_mod.X90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly1d_vert_w3_recon_alg_mod.X90 index 374325a37..23e244285 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly1d_vert_w3_recon_alg_mod.X90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly1d_vert_w3_recon_alg_mod.X90 @@ -12,7 +12,7 @@ module atlt_poly1d_vert_w3_recon_alg_mod use function_space_collection_mod, only : function_space_collection use finite_element_config_mod, only : element_order_h, element_order_v use fs_continuity_mod, only : W3 - use constants_mod, only : i_def, l_def, r_def + use constants_mod, only : i_def, l_def, r_def, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_DEBUG, & @@ -78,10 +78,9 @@ module atlt_poly1d_vert_w3_recon_alg_mod real(kind=r_def) :: reconstruction_reconstruction_input_inner_prod real(kind=r_def) :: tracer_tracer_input_inner_prod real(kind=r_def) :: inner2 - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables - real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def + real(kind=r_def), parameter :: overall_tolerance = 3100.0_r_def real(kind=r_def) :: machine_tol real(kind=r_def) :: relative_diff @@ -141,8 +140,8 @@ module atlt_poly1d_vert_w3_recon_alg_mod x_innerproduct_x( tracer_inner_prod, tracer ) ) ! Determining scale factors - reconstruction_sf = 1.0_r_def/(reconstruction_inner_prod + eps) - tracer_sf = 1.0_r_def/(tracer_inner_prod + eps) + reconstruction_sf = 1.0_r_def/(reconstruction_inner_prod + EPS) + tracer_sf = 1.0_r_def/(tracer_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + reconstruction_inner_prod*reconstruction_sf diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly_adv_update_alg_mod.X90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly_adv_update_alg_mod.X90 index c579342e5..cafc398f0 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly_adv_update_alg_mod.X90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_poly_adv_update_alg_mod.X90 @@ -13,7 +13,7 @@ module atlt_poly_adv_update_alg_mod use function_space_collection_mod, only : function_space_collection use finite_element_config_mod, only : element_order_h, element_order_v use fs_continuity_mod, only : W2H, Wtheta - use constants_mod, only : i_def, r_def, r_tran + use constants_mod, only : i_def, r_def, r_tran, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -61,7 +61,6 @@ module atlt_poly_adv_update_alg_mod real(kind=r_def) :: advective_advective_input_inner_prod real(kind=r_def) :: wind_wind_input_inner_prod real(kind=r_tran) :: inner2 - real(kind=r_tran), parameter :: eps = 1e-30_r_tran ! Test variables real(kind=r_tran), parameter :: overall_tolerance = 1500.0_r_tran @@ -103,8 +102,8 @@ module atlt_poly_adv_update_alg_mod x_innerproduct_x( wind_inner_prod, wind ) ) ! Determining scale factors - advective_sf = 1.0_r_tran/( real( advective_inner_prod, r_tran ) + eps ) - wind_sf = 1.0_r_tran/( real( wind_inner_prod, r_tran ) + eps ) + advective_sf = 1.0_r_tran/( real( advective_inner_prod, r_tran ) + EPS ) + wind_sf = 1.0_r_tran/( real( wind_inner_prod, r_tran ) + EPS ) inner1 = 0.0_r_tran inner1 = inner1 + real( advective_inner_prod, r_tran )*advective_sf diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_reconstruct_w3_field_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_reconstruct_w3_field_alg_mod.x90 index dc8b4c2c0..de518835c 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_reconstruct_w3_field_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_reconstruct_w3_field_alg_mod.x90 @@ -6,9 +6,10 @@ !> @brief Module containing handwritten adjoint test for atl_reconstruct_w3_field_alg module atlt_reconstruct_w3_field_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use field_mod, only : field_type use function_space_mod, only : function_space_type - use constants_mod, only : r_def, i_def, l_def + use constants_mod, only : r_def, i_def, l_def, EPS use log_mod, only : log_event, & log_scratch_space, & LOG_LEVEL_INFO, & @@ -37,9 +38,10 @@ module atlt_reconstruct_w3_field_alg_mod !> @details Passes if adjoint is transpose of tangent linear. !> Determined by testing the equality of inner products and , !> where M is the tangent linear and A is the adjoint. - !> @param[in] mesh The model mesh - !> @param[in] model_clock The model clock - subroutine atlt_reconstruct_w3_field_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_reconstruct_w3_field_alg( mesh, model_clock, adj_lookup_table_cache ) use atl_reconstruct_w3_field_alg_mod, only : atl_reconstruct_w3_field_alg use tl_reconstruct_w3_field_alg_mod, only : tl_reconstruct_w3_field_alg @@ -47,8 +49,10 @@ module atlt_reconstruct_w3_field_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache + ! Arguments for tl and adj calls type(field_type) :: field_new @@ -76,10 +80,9 @@ module atlt_reconstruct_w3_field_alg_mod real(kind=r_def) :: inner2 real(kind=r_def) :: field_new_field_new_input_inner_prod real(kind=r_def) :: field_old_field_old_input_inner_prod - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables - real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def + real(kind=r_def), parameter :: overall_tolerance = 3000.0_r_def real(kind=r_def) :: machine_tol real(kind=r_def) :: relative_diff @@ -122,8 +125,8 @@ module atlt_reconstruct_w3_field_alg_mod x_innerproduct_x( field_old_inner_prod, field_old ) ) ! Determining scale factors - field_new_sf = 1.0_r_def/(field_new_inner_prod + eps) - field_old_sf = 1.0_r_def/(field_old_inner_prod + eps) + field_new_sf = 1.0_r_def/(field_new_inner_prod + EPS) + field_old_sf = 1.0_r_def/(field_old_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + field_new_inner_prod*field_new_sf @@ -144,8 +147,9 @@ module atlt_reconstruct_w3_field_alg_mod field_old_field_old_input_inner_prod = 0.0_r_def ! Adjoint - call atl_reconstruct_w3_field_alg( field_new, field_old, ls_field_old, & - direction, transport_metadata, final_rk_stage ) + call atl_reconstruct_w3_field_alg( field_new, field_old, ls_field_old, & + direction, transport_metadata, final_rk_stage, & + adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( field_new_field_new_input_inner_prod, & @@ -215,10 +219,9 @@ module atlt_reconstruct_w3_field_alg_mod real(kind=r_def) :: inner2 real(kind=r_def) :: field_new_field_new_input_inner_prod real(kind=r_def) :: field_old_field_old_input_inner_prod - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables - real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def + real(kind=r_def), parameter :: overall_tolerance = 3000.0_r_def real(kind=r_def) :: machine_tol real(kind=r_def) :: relative_diff @@ -260,8 +263,8 @@ module atlt_reconstruct_w3_field_alg_mod x_innerproduct_x( field_old_inner_prod, field_old ) ) ! Determining scale factors - field_new_sf = 1.0_r_def/(field_new_inner_prod + eps) - field_old_sf = 1.0_r_def/(field_old_inner_prod + eps) + field_new_sf = 1.0_r_def/(field_new_inner_prod + EPS) + field_old_sf = 1.0_r_def/(field_old_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + field_new_inner_prod*field_new_sf diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_w3h_advective_update_alg_mod.X90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_w3h_advective_update_alg_mod.X90 index a66ed877c..1f942264d 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_w3h_advective_update_alg_mod.X90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_w3h_advective_update_alg_mod.X90 @@ -13,7 +13,7 @@ module atlt_w3h_advective_update_alg_mod use finite_element_config_mod, only : element_order_h, element_order_v use fs_continuity_mod, only : W2, W3 use operator_mod, only : operator_type - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -67,7 +67,6 @@ module atlt_w3h_advective_update_alg_mod real(kind=r_def) :: advective_increment_advective_increment_input_inner_prod real(kind=r_def) :: wind_wind_input_inner_prod real(kind=r_def) :: inner2 - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -115,8 +114,8 @@ module atlt_w3h_advective_update_alg_mod x_innerproduct_x(wind_inner_prod, wind) ) ! Determining scale factors - advective_increment_sf = 1.0_r_def/(advective_increment_inner_prod + eps) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + advective_increment_sf = 1.0_r_def/(advective_increment_inner_prod + EPS) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + advective_increment_inner_prod*advective_increment_sf diff --git a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_wt_advective_update_alg_mod.x90 b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_wt_advective_update_alg_mod.x90 index fc15d1db0..a00003edc 100644 --- a/applications/adjoint_tests/source/algorithm/transport/mol/atlt_wt_advective_update_alg_mod.x90 +++ b/applications/adjoint_tests/source/algorithm/transport/mol/atlt_wt_advective_update_alg_mod.x90 @@ -6,6 +6,7 @@ !> @brief Module containing handwritten adjoint test for atl_wt_advective_update_alg_mod routines module atlt_wt_advective_update_alg_mod + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use r_tran_field_mod, only : r_tran_field_type use field_mod, only : field_type use function_space_mod, only : function_space_type @@ -15,7 +16,7 @@ module atlt_wt_advective_update_alg_mod use finite_element_config_mod, only : element_order_h, & element_order_v use fs_continuity_mod, only : W2h, W2v, Wtheta, W2 - use constants_mod, only : i_def, r_def, l_def + use constants_mod, only : i_def, r_def, l_def, EPS use log_mod, only : log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -43,7 +44,10 @@ module atlt_wt_advective_update_alg_mod !> Determined by testing the equality of inner products !> < Mx, Mx > and < AMx, x >, where M is the tangent linear !> and A is the adjoint. - subroutine atlt_wt_advective_update_alg( mesh, model_clock ) + !> @param[in] mesh The model mesh + !> @param[in] model_clock The model clock + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atlt_wt_advective_update_alg( mesh, model_clock, adj_lookup_table_cache ) use atl_wt_advective_update_alg_mod, only : atl_wt_advective_update_alg use tl_wt_advective_update_alg_mod, only : tl_wt_advective_update_alg @@ -51,8 +55,9 @@ module atlt_wt_advective_update_alg_mod implicit none ! Arguments - type(mesh_type), pointer, intent(in) :: mesh - type(model_clock_type), intent(in) :: model_clock + type(mesh_type), pointer, intent(in) :: mesh + type(model_clock_type), intent(in) :: model_clock + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Arguments for tl and adj calls type(field_type) :: rhs @@ -87,7 +92,6 @@ module atlt_wt_advective_update_alg_mod real(kind=r_def) :: rhs_rhs_input_inner_prod real(kind=r_def) :: adv_field_adv_field_input_inner_prod real(kind=r_def) :: wind_wind_input_inner_prod - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -150,9 +154,9 @@ module atlt_wt_advective_update_alg_mod x_innerproduct_x( wind_inner_prod, wind ) ) ! Determining scale factors - rhs_sf = 1.0_r_def/(rhs_inner_prod + eps) - adv_field_sf = 1.0_r_def/(adv_field_inner_prod + eps) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + rhs_sf = 1.0_r_def/(rhs_inner_prod + EPS) + adv_field_sf = 1.0_r_def/(adv_field_inner_prod + EPS) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + rhs_inner_prod*rhs_sf @@ -178,10 +182,11 @@ module atlt_wt_advective_update_alg_mod wind_wind_input_inner_prod = 0.0_r_def ! Adjoint - call atl_wt_advective_update_alg( rhs, adv_field, wind, & - ls_adv_field, ls_wind, & - dt, direction, & - transport_metadata, final_rk_stage ) + call atl_wt_advective_update_alg( rhs, adv_field, wind, & + ls_adv_field, ls_wind, & + dt, direction, & + transport_metadata, final_rk_stage, & + adj_lookup_table_cache ) ! < AMx, x > call invoke( x_innerproduct_y( rhs_rhs_input_inner_prod, & @@ -253,7 +258,6 @@ module atlt_wt_advective_update_alg_mod real(kind=r_def) :: advective_advective_input_inner_prod real(kind=r_def) :: wind_wind_input_inner_prod real(kind=r_def) :: inner2 - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -288,8 +292,8 @@ module atlt_wt_advective_update_alg_mod x_innerproduct_x(wind_inner_prod, wind) ) ! Determining scale factors - advective_sf = 1.0_r_def/(advective_inner_prod + eps) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) + advective_sf = 1.0_r_def/(advective_inner_prod + EPS) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + advective_inner_prod*advective_sf @@ -376,7 +380,6 @@ module atlt_wt_advective_update_alg_mod real(kind=r_def) :: wind_wind_input_inner_prod real(kind=r_def) :: field_field_input_inner_prod real(kind=r_def) :: inner2 - real(kind=r_def), parameter :: eps = 1e-30_r_def ! Test parameters and variables real(kind=r_def), parameter :: overall_tolerance = 1500.0_r_def @@ -417,9 +420,9 @@ module atlt_wt_advective_update_alg_mod x_innerproduct_x(field_inner_prod, field) ) ! Determining scale factors - advective_sf = 1.0_r_def/(advective_inner_prod + eps) - wind_sf = 1.0_r_def/(wind_inner_prod + eps) - field_sf = 1.0_r_def/(field_inner_prod + eps) + advective_sf = 1.0_r_def/(advective_inner_prod + EPS) + wind_sf = 1.0_r_def/(wind_inner_prod + EPS) + field_sf = 1.0_r_def/(field_inner_prod + EPS) inner1 = 0.0_r_def inner1 = inner1 + advective_inner_prod*advective_sf diff --git a/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 b/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 index 9ebee3a42..9f426f45d 100644 --- a/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 +++ b/applications/adjoint_tests/source/driver/adjoint_test_driver_mod.f90 @@ -9,6 +9,8 @@ !> module adjoint_test_driver_mod + use adj_solver_lookup_cache_mod, only : adj_solver_lookup_cache_type + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use base_mesh_config_mod, only : prime_mesh_name use extrusion_mod, only : TWOD use fs_continuity_mod, only : Wtheta, W3 @@ -54,6 +56,9 @@ subroutine run( modeldb ) use adjt_poly_adv_upd_lookup_alg_mod, only : adjt_poly_adv_upd_lookup_alg use adjt_w3h_adv_upd_lookup_alg_mod, only : adjt_w3h_adv_upd_lookup_alg + ! ./linear_physics + use atlt_bl_inc_alg_mod, only : atlt_bl_inc_alg + ! Handwritten algorithm tests ! ./interpolation use adjt_interpolation_alg_mod, only : adjt_interp_w3wth_to_w2_alg, & @@ -103,6 +108,9 @@ subroutine run( modeldb ) use adjt_mixed_solver_alg_mod, only : adjt_mixed_solver_alg use adjt_semi_implicit_solver_step_alg_mod, only : adjt_semi_implicit_solver_step_alg + ! ./linear_physics + use atlt_bdy_lyr_alg_mod, only : atlt_bdy_lyr_alg + ! ./timestepping use atlt_si_timestep_alg_mod, only : atlt_si_timestep_alg @@ -112,15 +120,19 @@ subroutine run( modeldb ) type(modeldb_type), target, intent(inout) :: modeldb ! Internal variables - type(field_type), pointer :: chi(:) - type(field_type), pointer :: panel_id - type(mesh_type), pointer :: mesh - type(mesh_type), pointer :: twod_mesh + type(field_type), pointer :: chi(:) + type(field_type), pointer :: panel_id + type(mesh_type), pointer :: mesh + type(mesh_type), pointer :: twod_mesh + type(adj_solver_lookup_cache_type) :: adj_solver_lookup_cache + type(adj_trans_lookup_cache_type) :: adj_trans_lookup_cache mesh => mesh_collection%get_mesh( prime_mesh_name ) chi => get_coordinates( mesh%get_id() ) panel_id => get_panel_id( mesh%get_id() ) twod_mesh => mesh_collection%get_mesh( mesh, TWOD ) + call adj_solver_lookup_cache%initialise(mesh) + call adj_trans_lookup_cache%initialise(mesh) call log_event( "TESTING generated adjoint kernels", LOG_LEVEL_INFO ) call run_gen_adj_kernel_tests( mesh, chi, panel_id ) @@ -132,15 +144,18 @@ subroutine run( modeldb ) call atlt_poly1d_vert_w3_recon_alg( mesh ) call atlt_w3h_advective_update_alg( mesh ) ! -- Lookup table solutions. - call adjt_poly1d_recon_lookup_alg( mesh ) - call adjt_poly2d_recon_lookup_alg( mesh, Wtheta ) - call adjt_poly2d_recon_lookup_alg( mesh, W3 ) - call adjt_poly_adv_upd_lookup_alg( mesh ) - call adjt_w3h_adv_upd_lookup_alg( mesh ) + call adjt_poly1d_recon_lookup_alg( mesh, adj_trans_lookup_cache ) + call adjt_poly2d_recon_lookup_alg( mesh, Wtheta, adj_trans_lookup_cache ) + call adjt_poly2d_recon_lookup_alg( mesh, W3, adj_trans_lookup_cache ) + call adjt_poly_adv_upd_lookup_alg( mesh, adj_trans_lookup_cache ) + call adjt_w3h_adv_upd_lookup_alg( mesh, adj_trans_lookup_cache ) ! ./core_dynamics call atlt_pressure_gradient_bd_alg( mesh ) + ! ./linear_physics + call atlt_bl_inc_alg( mesh ) + ! ./inter_function_space call adjt_sci_convert_hdiv_field_alg( mesh, chi, panel_id ) @@ -162,26 +177,26 @@ subroutine run( modeldb ) call atlt_end_con_step_alg( mesh, modeldb%clock ) ! ./transport/mol - call adjt_hori_w3_reconstruct_alg( mesh, modeldb%clock ) + call adjt_hori_w3_reconstruct_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) call atlt_vert_w3_reconstruct_alg( mesh, modeldb%clock ) - call atlt_reconstruct_w3_field_alg( mesh, modeldb%clock ) + call atlt_reconstruct_w3_field_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) call atlt_hori_wt_update_alg( mesh, modeldb%clock ) call atlt_vert_wt_update_alg( mesh, modeldb%clock ) - call adjt_hori_wt_update_alg( mesh, modeldb%clock ) - call atlt_wt_advective_update_alg( mesh, modeldb%clock ) - call atlt_advective_and_flux_alg( mesh, modeldb%clock ) - call atlt_mol_conservative_alg( mesh, modeldb%clock ) - call atlt_mol_advective_alg( mesh, modeldb%clock ) + call adjt_hori_wt_update_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) + call atlt_wt_advective_update_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) + call atlt_advective_and_flux_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) + call atlt_mol_conservative_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) + call atlt_mol_advective_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) ! ./transport/control - call atlt_transport_field_alg( mesh, modeldb%clock ) - call atlt_wind_transport_alg( mesh, modeldb%clock ) - call atlt_moist_mr_transport_alg( mesh, modeldb%clock ) - call atlt_theta_transport_alg( mesh, modeldb%clock ) + call atlt_transport_field_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) + call atlt_wind_transport_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) + call atlt_moist_mr_transport_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) + call atlt_theta_transport_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) call adjt_ls_wind_pert_rho_initialiser_alg( mesh, modeldb%clock ) call adjt_pert_wind_ls_rho_initialiser_alg( mesh, modeldb%clock ) call atlt_transport_controller_initialiser_alg( mesh, modeldb%clock ) - call atlt_transport_control_alg( mesh, modeldb%clock ) + call atlt_transport_control_alg( mesh, modeldb%clock, adj_trans_lookup_cache ) ! ./core_dynamics call atlt_rhs_alg( mesh, modeldb%clock ) @@ -189,12 +204,15 @@ subroutine run( modeldb ) call atlt_derive_exner_from_eos_alg( mesh ) call atlt_moist_dyn_factors_alg( mesh ) + ! ./linear_physics + call atlt_bdy_lyr_alg( modeldb, mesh ) + ! ./solver - call adjt_pressure_precon_alg( modeldb, mesh, modeldb%clock ) + call adjt_pressure_precon_alg( modeldb, mesh, modeldb%clock, adj_solver_lookup_cache ) call adjt_mixed_operator_alg( mesh, modeldb%clock ) - call adjt_mixed_schur_preconditioner_alg( modeldb, mesh, modeldb%clock ) - call adjt_mixed_solver_alg( modeldb, mesh, modeldb%clock ) - call adjt_semi_implicit_solver_step_alg( modeldb, mesh, modeldb%clock ) + call adjt_mixed_schur_preconditioner_alg( modeldb, mesh, modeldb%clock, adj_solver_lookup_cache ) + call adjt_mixed_solver_alg( modeldb, mesh, modeldb%clock, adj_solver_lookup_cache ) + call adjt_semi_implicit_solver_step_alg( modeldb, mesh, modeldb%clock, adj_solver_lookup_cache ) ! ./timestepping call atlt_si_timestep_alg( modeldb, mesh, twod_mesh, 1 ) @@ -202,6 +220,9 @@ subroutine run( modeldb ) call log_event( "TESTING COMPLETE", LOG_LEVEL_INFO ) + call adj_solver_lookup_cache%finalise() + call adj_trans_lookup_cache%finalise() + end subroutine run end module adjoint_test_driver_mod diff --git a/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 b/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 index 09f74b4c9..9db0ddb99 100644 --- a/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 +++ b/applications/adjoint_tests/source/driver/adjoint_test_parameters_mod.F90 @@ -28,12 +28,12 @@ module adjoint_test_parameters_mod ! if the ls is not realistic. ls can still be ! randomly assigned, but in a sensible range ! to prevent these issues. - real(r_def), dimension(2), parameter :: ls_u_range = (/ 0.0_r_def, 10.0_r_def /) + real(r_def), dimension(2), parameter :: ls_u_range = (/ 1.e2_r_def, 1.e3_r_def /) real(r_def), dimension(2), parameter :: ls_theta_range = (/ 280.0_r_def, 340.0_r_def /) - real(r_def), dimension(2), parameter :: ls_rho_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_exner_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md1_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md2_range = (/ 0.0_r_def, 1.0_r_def /) - real(r_def), dimension(2), parameter :: ls_md3_range = (/ 0.0_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_rho_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_exner_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md1_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md2_range = (/ 0.1_r_def, 1.0_r_def /) + real(r_def), dimension(2), parameter :: ls_md3_range = (/ 0.1_r_def, 1.0_r_def /) end module adjoint_test_parameters_mod diff --git a/applications/gravity_wave/example/iodef.xml b/applications/gravity_wave/example/iodef.xml index 93ceb52c1..b7156638d 100644 --- a/applications/gravity_wave/example/iodef.xml +++ b/applications/gravity_wave/example/iodef.xml @@ -103,7 +103,7 @@ performance - 1.0 + 1.0 diff --git a/applications/gravity_wave/rose-meta/lfric-gravity_wave/version30_31.py b/applications/gravity_wave/rose-meta/lfric-gravity_wave/version30_31.py new file mode 100644 index 000000000..700307114 --- /dev/null +++ b/applications/gravity_wave/rose-meta/lfric-gravity_wave/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gravity_wave + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/gravity_wave/rose-meta/lfric-gravity_wave/versions.py b/applications/gravity_wave/rose-meta/lfric-gravity_wave/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/gravity_wave/rose-meta/lfric-gravity_wave/versions.py +++ b/applications/gravity_wave/rose-meta/lfric-gravity_wave/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/gravity_wave/rose-meta/lfric-gravity_wave/vn3.1/rose-meta.conf b/applications/gravity_wave/rose-meta/lfric-gravity_wave/vn3.1/rose-meta.conf new file mode 100644 index 000000000..ae73c5287 --- /dev/null +++ b/applications/gravity_wave/rose-meta/lfric-gravity_wave/vn3.1/rose-meta.conf @@ -0,0 +1,31 @@ +import=lfric-gungho/vn3.1 + +[namelist:gravity_wave_constants] +compulsory=true +description= +ns=namelist/gw_constants +title=Gravity wave constants + +[namelist:gravity_wave_constants=b_space] +compulsory=true +description=????? +!enumeration=true +help=????? +sort-key= +value-titles=w0, w3, wtheta +values='w0', 'w3', 'wtheta' + +[!namelist:gravity_wave_constants=cs_square] +compulsory=false +description= +!expression=namelist:gravity_wave_constants=speed_of_sound*namelist:gravity_wave_constants=speed_of_sound +help= +!kind=default +sort-key= +type=real + +[namelist:gravity_wave_constants=speed_of_sound] +compulsory=true +description= +!kind=default +type=real diff --git a/applications/gravity_wave/source/algorithm/gravity_wave_alg_mod.x90 b/applications/gravity_wave/source/algorithm/gravity_wave_alg_mod.x90 index f5a9bbd93..59b1a432d 100644 --- a/applications/gravity_wave/source/algorithm/gravity_wave_alg_mod.x90 +++ b/applications/gravity_wave/source/algorithm/gravity_wave_alg_mod.x90 @@ -66,7 +66,8 @@ module gravity_wave_alg_mod use field_indices_mod, only: igw_u, igw_p, igw_b use copy_field_alg_mod, only: copy_field - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -525,12 +526,12 @@ contains real(kind=r_second) :: dt real(kind=r_def) :: bvf_square integer(kind=i_def) :: b_space - logical(kind=l_def) :: subroutine_timers ! Auxiliary constants to group invokes real(kind=r_def) :: const1, const2 + integer(tik) :: id - if ( subroutine_timers ) call timer('gravity_wave_alg') + if ( LPROF ) call start_timing( id, 'gravity_wave_alg' ) ! Pointers to namelists timestepping_nml => modeldb%configuration%get_namelist('timestepping') @@ -540,7 +541,6 @@ contains ! Obtain namelist parameters call timestepping_nml%get_value( 'dt', dt ) call initial_temperature_nml%get_value( 'bvf_square', bvf_square ) - call io_nml%get_value( 'subroutine_timers', subroutine_timers ) !=== Do a single timestep ==============================================! mesh => wind%get_mesh() @@ -638,7 +638,7 @@ contains nullify( mesh ) - if ( subroutine_timers ) call timer('gravity_wave_alg') + if ( LPROF ) call stop_timing( id, 'gravity_wave_alg' ) end subroutine gravity_wave_alg_step diff --git a/applications/gravity_wave/source/algorithm/gw_mixed_diag_precon_alg_mod.x90 b/applications/gravity_wave/source/algorithm/gw_mixed_diag_precon_alg_mod.x90 index 228c8ff52..054ab7fec 100644 --- a/applications/gravity_wave/source/algorithm/gw_mixed_diag_precon_alg_mod.x90 +++ b/applications/gravity_wave/source/algorithm/gw_mixed_diag_precon_alg_mod.x90 @@ -16,7 +16,6 @@ module gw_mixed_diag_precon_alg_mod use constants_mod, only: i_def - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -26,7 +25,8 @@ module gw_mixed_diag_precon_alg_mod use copy_field_alg_mod, only: copy_field use sci_preconditioner_mod, only: abstract_preconditioner_type use sci_r_solver_field_vector_mod, only: r_solver_field_vector_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use vector_mod, only: abstract_vector_type implicit none @@ -174,8 +174,9 @@ contains y_vec_u => null(), & y_vec_p => null(), & y_vec_b => null() + integer(tik) :: id - if ( subroutine_timers ) call timer('gw_mixed_diag_precon_alg') + if ( LPROF ) call start_timing( id, 'gw_mixed_diag_precon_alg' ) select type(x) type is(r_solver_field_vector_type) @@ -212,7 +213,7 @@ contains nullify( x_vec_u, x_vec_p, x_vec_b, y_vec_u, y_vec_p, y_vec_b ) - if ( subroutine_timers ) call timer('gw_mixed_diag_precon_alg') + if ( LPROF ) call stop_timing( id, 'gw_mixed_diag_precon_alg' ) end subroutine apply_gw_mixed_diag_preconditioner diff --git a/applications/gravity_wave/source/algorithm/gw_mixed_schur_precon_alg_mod.x90 b/applications/gravity_wave/source/algorithm/gw_mixed_schur_precon_alg_mod.x90 index 79ff8630b..d109d6c6e 100644 --- a/applications/gravity_wave/source/algorithm/gw_mixed_schur_precon_alg_mod.x90 +++ b/applications/gravity_wave/source/algorithm/gw_mixed_schur_precon_alg_mod.x90 @@ -89,8 +89,8 @@ module gw_mixed_schur_precon_alg_mod use sci_preconditioner_mod, only: abstract_preconditioner_type use sci_r_solver_field_vector_mod, only: r_solver_field_vector_type use field_indices_mod, only: igw_u, igw_p, igw_b - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -350,9 +350,10 @@ contains type(r_solver_field_type), pointer :: y_vec_u => null(), & y_vec_p => null(), & y_vec_b => null() + integer(tik) :: id - if ( subroutine_timers ) call timer('gw_mixed_schur_precon_alg') + if ( LPROF ) call start_timing( id, 'gw_mixed_schur_precon_alg' ) select type(x) type is(r_solver_field_vector_type) @@ -399,7 +400,7 @@ contains nullify( y_vec_u, y_vec_p, y_vec_b ) - if ( subroutine_timers ) call timer('gw_mixed_schur_precon_alg') + if ( LPROF ) call stop_timing( id, 'gw_mixed_schur_precon_alg' ) end subroutine apply_gw_mixed_schur_preconditioner diff --git a/applications/gravity_wave/source/driver/gravity_wave_infrastructure_mod.f90 b/applications/gravity_wave/source/driver/gravity_wave_infrastructure_mod.f90 index 46b88ddad..0526e935b 100644 --- a/applications/gravity_wave/source/driver/gravity_wave_infrastructure_mod.f90 +++ b/applications/gravity_wave/source/driver/gravity_wave_infrastructure_mod.f90 @@ -10,7 +10,6 @@ module gravity_wave_infrastructure_mod use add_mesh_map_mod, only : assign_mesh_maps use driver_modeldb_mod, only : modeldb_type - use check_configuration_mod, only : get_required_stencil_depth use constants_mod, only : i_def, & PRECISION_REAL, & r_def, r_second, & @@ -81,7 +80,8 @@ subroutine initialise_infrastructure( program_name, & logical(l_def) :: prepartitioned logical :: apply_partition_check - integer(i_def) :: stencil_depth + integer(i_def) :: stencil_depth(1) + integer(i_def) :: geometry integer(i_def) :: method integer(i_def) :: number_of_layers @@ -191,7 +191,7 @@ subroutine initialise_infrastructure( program_name, & !======================================================================= ! 1.3 Initialise mesh objects and assign InterGrid maps !======================================================================= - stencil_depth = get_required_stencil_depth() + stencil_depth = 2 apply_partition_check = .false. if ( .not. prepartitioned .and. l_multigrid ) then apply_partition_check = .true. @@ -237,6 +237,9 @@ subroutine initialise_infrastructure( program_name, & nullify(chi_inventory, panel_id_inventory) deallocate(base_mesh_names) + deallocate(twod_names) + deallocate(extrusion) + deallocate(extrusion_2d) end subroutine initialise_infrastructure diff --git a/applications/gravity_wave/source/gravity_wave.f90 b/applications/gravity_wave/source/gravity_wave.f90 index 2c269c11e..e7eb7ffe6 100644 --- a/applications/gravity_wave/source/gravity_wave.f90 +++ b/applications/gravity_wave/source/gravity_wave.f90 @@ -11,39 +11,47 @@ program gravity_wave - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use driver_modeldb_mod, only: modeldb_type use driver_collections_mod, only: init_collections, final_collections use driver_comm_mod, only: init_comm, final_comm use driver_config_mod, only: init_config, final_config use driver_log_mod, only: init_logger, final_logger use driver_time_mod, only: init_time, final_time - use driver_timer_mod, only: init_timers, final_timers use gravity_wave_mod, only: gravity_wave_required_namelists use gravity_wave_driver_mod, only: initialise, step, finalise use lfric_mpi_mod, only: global_mpi use log_mod, only: log_event, & log_level_trace, & log_scratch_space + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path implicit none - type(modeldb_type) :: modeldb - character(*), parameter :: program_name = "gravity_wave" - character(:), allocatable :: filename + type(modeldb_type) :: modeldb + character(*), parameter :: program_name = "gravity_wave" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) call modeldb%configuration%initialise( program_name, table_len=10 ) modeldb%mpi => global_mpi call init_comm( program_name, modeldb ) - call get_initial_filename( filename ) call init_config( filename, gravity_wave_required_namelists, & modeldb%configuration ) deallocate( filename ) call init_logger( modeldb%mpi%get_comm(), program_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, program_name, timer_output_path ) + nullify( io_nml ) call init_collections() - call init_timers( program_name ) call init_time( modeldb ) ! Create the depository field collection and place it in modeldb @@ -63,8 +71,8 @@ program gravity_wave call finalise( program_name, modeldb ) call final_time( modeldb ) - call final_timers( program_name ) call final_collections() + call final_timing( program_name ) call final_logger( program_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/gravity_wave/unit-test/kernel/initial_buoyancy_kernel_mod_test.pf b/applications/gravity_wave/unit-test/kernel/initial_buoyancy_kernel_mod_test.pf index 8a3ca705d..be9f43f92 100644 --- a/applications/gravity_wave/unit-test/kernel/initial_buoyancy_kernel_mod_test.pf +++ b/applications/gravity_wave/unit-test/kernel/initial_buoyancy_kernel_mod_test.pf @@ -77,7 +77,7 @@ contains p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/applications/gungho_model/example/configuration.nml b/applications/gungho_model/example/configuration.nml index ea60b8aa1..aa74a254d 100644 --- a/applications/gungho_model/example/configuration.nml +++ b/applications/gungho_model/example/configuration.nml @@ -286,6 +286,7 @@ tau_u=0.55, / &transport adjust_theta=.false., +adjust_tracer_equation=.false. adjust_vhv_wind=.true., broken_w2_projection=.false., calculate_detj='upwind', diff --git a/applications/gungho_model/example/file_def_initial.xml b/applications/gungho_model/example/file_def_initial.xml index 2b1050253..42cf3bfec 100644 --- a/applications/gungho_model/example/file_def_initial.xml +++ b/applications/gungho_model/example/file_def_initial.xml @@ -13,6 +13,8 @@ + + diff --git a/applications/gungho_model/example/iodef.xml b/applications/gungho_model/example/iodef.xml index 9f2600514..200d45eae 100644 --- a/applications/gungho_model/example/iodef.xml +++ b/applications/gungho_model/example/iodef.xml @@ -41,7 +41,7 @@ performance - 1.0 + 1.0 diff --git a/applications/gungho_model/example/iodef_climate.xml b/applications/gungho_model/example/iodef_climate.xml index e4bc3a888..429b0160e 100644 --- a/applications/gungho_model/example/iodef_climate.xml +++ b/applications/gungho_model/example/iodef_climate.xml @@ -41,7 +41,7 @@ performance - 1.0 + 1.0 diff --git a/applications/gungho_model/example/iodef_lam.xml b/applications/gungho_model/example/iodef_lam.xml index 8c3417421..c85d7503a 100644 --- a/applications/gungho_model/example/iodef_lam.xml +++ b/applications/gungho_model/example/iodef_lam.xml @@ -42,7 +42,7 @@ performance - 1.0 + 1.0 diff --git a/applications/gungho_model/example/iodef_nwp.xml b/applications/gungho_model/example/iodef_nwp.xml index 6c8a69c76..cc2410726 100644 --- a/applications/gungho_model/example/iodef_nwp.xml +++ b/applications/gungho_model/example/iodef_nwp.xml @@ -41,7 +41,7 @@ performance - 1.0 + 1.0 diff --git a/applications/gungho_model/lam_example/baroclinic/config_driver.nml b/applications/gungho_model/lam_example/baroclinic/config_driver.nml index 43d72b197..0aea85072 100644 --- a/applications/gungho_model/lam_example/baroclinic/config_driver.nml +++ b/applications/gungho_model/lam_example/baroclinic/config_driver.nml @@ -210,6 +210,7 @@ log_space = .true., .false., .false. enforce_min_value=.false.,.false.,.false. max_vert_cfl_calc='uniform' min_value=0.0,0.0,-99999999.0,0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. calculate_detj='upwind', cap_density_predictor = 0.01 diff --git a/applications/gungho_model/lam_example/baroclinic/config_lam.nml b/applications/gungho_model/lam_example/baroclinic/config_lam.nml index d63ada536..7187243e9 100644 --- a/applications/gungho_model/lam_example/baroclinic/config_lam.nml +++ b/applications/gungho_model/lam_example/baroclinic/config_lam.nml @@ -226,6 +226,7 @@ log_space = .true., .false., .false. enforce_min_value=.false.,.false.,.false. max_vert_cfl_calc='uniform' min_value=0.0,0.0,-99999999.0,0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. calculate_detj='upwind', cap_density_predictor = 0.01 diff --git a/applications/gungho_model/lam_example/baroclinic/iodef.xml b/applications/gungho_model/lam_example/baroclinic/iodef.xml index adcc5a03d..df6dbb0b9 100644 --- a/applications/gungho_model/lam_example/baroclinic/iodef.xml +++ b/applications/gungho_model/lam_example/baroclinic/iodef.xml @@ -369,7 +369,7 @@ performance - 1.0 + 1.0 diff --git a/applications/gungho_model/lam_example/straka/config_driver.nml b/applications/gungho_model/lam_example/straka/config_driver.nml index 82fd2d418..094790169 100644 --- a/applications/gungho_model/lam_example/straka/config_driver.nml +++ b/applications/gungho_model/lam_example/straka/config_driver.nml @@ -211,6 +211,7 @@ log_space = .true., .false., .false. enforce_min_value=.false.,.false.,.false. max_vert_cfl_calc='uniform' min_value=0.0,0.0,-99999999.0,0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. calculate_detj='upwind', cap_density_predictor = 0.01 diff --git a/applications/gungho_model/lam_example/straka/config_lam.nml b/applications/gungho_model/lam_example/straka/config_lam.nml index 636c9e6e0..30a4ea4b8 100644 --- a/applications/gungho_model/lam_example/straka/config_lam.nml +++ b/applications/gungho_model/lam_example/straka/config_lam.nml @@ -223,6 +223,7 @@ log_space = .true., .false., .false. enforce_min_value=.false.,.false.,.false. max_vert_cfl_calc='uniform' min_value=0.0,0.0,-99999999.0,0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. calculate_detj='upwind', cap_density_predictor = 0.01 diff --git a/applications/gungho_model/lam_example/straka/iodef.xml b/applications/gungho_model/lam_example/straka/iodef.xml index a9b48b1bf..4dc78bad4 100644 --- a/applications/gungho_model/lam_example/straka/iodef.xml +++ b/applications/gungho_model/lam_example/straka/iodef.xml @@ -369,7 +369,7 @@ performance - 1.0 + 1.0 diff --git a/applications/gungho_model/optimisation/uoe-dial3 b/applications/gungho_model/optimisation/uoe-dial3 new file mode 120000 index 000000000..e5b7210c6 --- /dev/null +++ b/applications/gungho_model/optimisation/uoe-dial3 @@ -0,0 +1 @@ +meto-ex1a \ No newline at end of file diff --git a/applications/gungho_model/optimisation/uoe-dial3/psykal/global.py b/applications/gungho_model/optimisation/uoe-dial3/psykal/global.py deleted file mode 100644 index 125a77f40..000000000 --- a/applications/gungho_model/optimisation/uoe-dial3/psykal/global.py +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################## -# Copyright (c) 2017, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## - - -''' -PSyclone transformation script for the LFRic (Dynamo0p3) API to apply -colouring, OpenMP and redundant computation to the level-1 halo for -the initialisation built-ins generically. - -''' - -from psyclone_tools import (redundant_computation_setval, colour_loops, - openmp_parallelise_loops, - view_transformed_schedule) - - -def trans(psyir): - ''' - Applies PSyclone colouring, OpenMP and redundant computation - transformations. - - :param psyir: the PSyIR of the PSyIR-layer. - :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` - - ''' - redundant_computation_setval(psyir) - colour_loops(psyir) - openmp_parallelise_loops(psyir) - view_transformed_schedule(psyir) diff --git a/applications/gungho_model/optimisation/uoe-epic b/applications/gungho_model/optimisation/uoe-epic new file mode 120000 index 000000000..e5b7210c6 --- /dev/null +++ b/applications/gungho_model/optimisation/uoe-epic @@ -0,0 +1 @@ +meto-ex1a \ No newline at end of file diff --git a/applications/gungho_model/optimisation/uoe-epic/psykal/global.py b/applications/gungho_model/optimisation/uoe-epic/psykal/global.py deleted file mode 100644 index 125a77f40..000000000 --- a/applications/gungho_model/optimisation/uoe-epic/psykal/global.py +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################## -# Copyright (c) 2017, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## - - -''' -PSyclone transformation script for the LFRic (Dynamo0p3) API to apply -colouring, OpenMP and redundant computation to the level-1 halo for -the initialisation built-ins generically. - -''' - -from psyclone_tools import (redundant_computation_setval, colour_loops, - openmp_parallelise_loops, - view_transformed_schedule) - - -def trans(psyir): - ''' - Applies PSyclone colouring, OpenMP and redundant computation - transformations. - - :param psyir: the PSyIR of the PSyIR-layer. - :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` - - ''' - redundant_computation_setval(psyir) - colour_loops(psyir) - openmp_parallelise_loops(psyir) - view_transformed_schedule(psyir) diff --git a/applications/gungho_model/rose-meta/lfric-gungho_model/version30_31.py b/applications/gungho_model/rose-meta/lfric-gungho_model/version30_31.py new file mode 100644 index 000000000..cc668fd4b --- /dev/null +++ b/applications/gungho_model/rose-meta/lfric-gungho_model/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho_model + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/gungho_model/rose-meta/lfric-gungho_model/versions.py b/applications/gungho_model/rose-meta/lfric-gungho_model/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/gungho_model/rose-meta/lfric-gungho_model/versions.py +++ b/applications/gungho_model/rose-meta/lfric-gungho_model/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/gungho_model/rose-meta/lfric-gungho_model/vn3.1/rose-meta.conf b/applications/gungho_model/rose-meta/lfric-gungho_model/vn3.1/rose-meta.conf new file mode 100644 index 000000000..47acbb91f --- /dev/null +++ b/applications/gungho_model/rose-meta/lfric-gungho_model/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-gungho/vn3.1 diff --git a/applications/gungho_model/source/gungho_model.f90 b/applications/gungho_model/source/gungho_model.f90 index 4367d93c4..ee8699e43 100644 --- a/applications/gungho_model/source/gungho_model.f90 +++ b/applications/gungho_model/source/gungho_model.f90 @@ -15,7 +15,7 @@ program gungho_model - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use derived_config_mod, only: l_esm_couple use driver_collections_mod, only: init_collections, final_collections use driver_comm_mod, only: init_comm, final_comm @@ -23,7 +23,6 @@ program gungho_model use driver_counter_mod, only: init_counters, final_counters use driver_log_mod, only: init_logger, final_logger use driver_time_mod, only: init_time, final_time - use driver_timer_mod, only: init_timers, final_timers use gungho_mod, only: gungho_required_namelists use gungho_driver_mod, only: initialise, step, finalise use driver_modeldb_mod, only: modeldb_type @@ -32,14 +31,22 @@ program gungho_model log_level_info, & log_level_trace, & log_scratch_space + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path + implicit none ! Model run working data set type(modeldb_type) :: modeldb - character(*), parameter :: application_name = "gungho_model" - character(:), allocatable :: filename + character(*), parameter :: application_name = "gungho_model" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) modeldb%mpi => global_mpi @@ -66,11 +73,14 @@ program gungho_model call modeldb%io_contexts%initialise(application_name, 100) call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) + call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) - call init_timers( application_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, application_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) call init_counters( application_name ) @@ -99,7 +109,7 @@ program gungho_model call final_counters( application_name ) call final_time( modeldb ) call final_collections() - call final_timers( application_name ) + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/jedi_lfric_tests/example/configuration.nml b/applications/jedi_lfric_tests/example/configuration.nml index b2d3c1ff0..ab6828519 100644 --- a/applications/jedi_lfric_tests/example/configuration.nml +++ b/applications/jedi_lfric_tests/example/configuration.nml @@ -1,13 +1,13 @@ &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -29,16 +29,25 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, -dl_type='latitude', +dl_type='standard', / &departure_points horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -56,13 +65,13 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/Quagga/C12/n96e_l70', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='restart', diag_stem_name='diagGungho', -ls_directory='/data/users/lfric/data/tangent-linear/Ticket46', -ls_filename='final_ls', -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid', -start_dump_directory='/data/users/lfric/data/tangent-linear/Ticket3590', +ls_directory='/data/users/lfricadmin/data/tangent-linear/PullRequest182' +ls_filename='final_ls_with_land', +orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', +start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', start_dump_filename='final_pert', / &finite_element @@ -79,10 +88,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -90,7 +99,7 @@ p2theta_vert=.true., rotating=.true., shallow=.true., si_momentum_equation=.false., -theta_moist_source=.false. +theta_moist_source=.false., use_multires_coupling=.false., use_physics=.true., use_wavedynamics=.true., @@ -101,15 +110,27 @@ gcrk=8, method='prec_only', monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', +preconditioner='multigrid', si_pressure_a_tol=1.0e-8, si_pressure_maximum_iterations=400, si_pressure_tolerance=1.0e-4, / +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau +/ &idealised f_lon_deg=0.0, -perturb_init=.false. -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -144,10 +165,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -159,7 +180,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -168,22 +189,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -196,11 +220,16 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, pert_option='file', +transport_efficiency=.true., / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver @@ -211,7 +240,7 @@ guess_np1=.false., mixed_solver_a_tol=1.0e-3, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600., +reference_reset_time=3600.0, si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', @@ -224,6 +253,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -231,16 +268,23 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', -panel_xproc=6, +panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +bl_segment=0, +configure_segments=.true., +conv_gr_segment=16, +gw_segment=0, limit_drag_incs=.false., +ls_ppn_segment=0, sample_physics_scalars=.true., sample_physics_winds=.true., -configure_segments=.false. +sample_physics_winds_correction=.false., +ussp_segment=0, / &planet cp=1005.0, @@ -252,10 +296,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -268,11 +316,13 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', @@ -286,6 +336,8 @@ monitor_convergence=.false., preconditioner='diagonal', tolerance=1.0e-6, / +&specified_surface +/ &time calendar='timestep', calendar_origin='2016-01-01 15:00:00', @@ -297,7 +349,7 @@ timestep_start='1', ×tepping alpha=0.55, dt=1800, -inner_iterations=2, +inner_iterations=1, method='semi_implicit', outer_iterations=2, runge_kutta_method='forward_euler', @@ -308,6 +360,7 @@ tau_u=0.55, / &transport adjust_theta=.false., +adjust_tracer_equation=.false., adjust_vhv_wind=.false., ageofair_reset_level=10, broken_w2_projection=.false., @@ -341,8 +394,8 @@ min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false., -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', @@ -360,8 +413,7 @@ vertical_method=5*1, vertical_monotone=5*1, vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example/iodef.xml b/applications/jedi_lfric_tests/example/iodef.xml index 368ff5621..90edb87ac 100644 --- a/applications/jedi_lfric_tests/example/iodef.xml +++ b/applications/jedi_lfric_tests/example/iodef.xml @@ -50,6 +50,11 @@ + + + + + @@ -140,6 +145,8 @@ + + @@ -186,6 +193,8 @@ + + @@ -327,6 +336,7 @@ + @@ -337,7 +347,7 @@ performance - 1.0 + 1.0 diff --git a/applications/jedi_lfric_tests/example/mesh_C12.nc b/applications/jedi_lfric_tests/example/mesh_C12_MG.nc similarity index 64% rename from applications/jedi_lfric_tests/example/mesh_C12.nc rename to applications/jedi_lfric_tests/example/mesh_C12_MG.nc index f7ea6988e..ebe518907 100644 Binary files a/applications/jedi_lfric_tests/example/mesh_C12.nc and b/applications/jedi_lfric_tests/example/mesh_C12_MG.nc differ diff --git a/applications/jedi_lfric_tests/example_create_traj/C224_create_traj_file.sh b/applications/jedi_lfric_tests/example_create_traj/C224_create_traj_file.sh new file mode 100755 index 000000000..22ba50324 --- /dev/null +++ b/applications/jedi_lfric_tests/example_create_traj/C224_create_traj_file.sh @@ -0,0 +1,19 @@ +# This input file can be generated by running the lfric_atm nightly test suite +# It is generated by the nwp_gal9_ls_and_jedi-C224_MG test +INPUT=ls_and_jedi_trajectory_2021060200-2021060207.nc +OUTPUT=C224_jedi_trajectory.nc + +TIMESTEP=$(ncks -d time,0 -v time ${INPUT} | grep "time =" | sed -e "s/.*= //;s/ .*//" | tr -d -c 0-9) + +echo Altering variable names to match JEDI/MONIO +# Change the file so that the time starts at 0, not 3600 +ncrename -d time,time_counter ${INPUT} ${INPUT}_tmp +ncrename -O -v time,time_instant ${INPUT}_tmp ${INPUT}_tmp +ncrename -O -v time_bounds,time_instant_bounds ${INPUT}_tmp ${INPUT}_tmp + +echo Shifting time back by ${TIMESTEP} +# Change the file so that the time starts at 0 +ncap2 -O -s time_instant-=${TIMESTEP} ${INPUT}_tmp ${INPUT}_tmp +ncap2 -O -s time_instant_bounds-=${TIMESTEP} ${INPUT}_tmp ${OUTPUT} +rm *tmp* +echo Output ${OUTPUT} diff --git a/applications/jedi_lfric_tests/example_forecast/configuration.nml b/applications/jedi_lfric_tests/example_forecast/configuration.nml index 016e61fbc..220c17be0 100644 --- a/applications/jedi_lfric_tests/example_forecast/configuration.nml +++ b/applications/jedi_lfric_tests/example_forecast/configuration.nml @@ -7,7 +7,7 @@ test_field='theta', &jedi_geometry io_calender_start='2018-04-14T21:00:00', io_path_inc_read='', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.false., io_time_step='P0DT1H0M0S', @@ -309,6 +309,7 @@ tau_u=0.5, / &transport adjust_theta=.false., +adjust_tracer_equation=.false. adjust_vhv_wind=.false., ageofair_reset_level=10, broken_w2_projection=.false., diff --git a/applications/jedi_lfric_tests/example_forecast/iodef.xml b/applications/jedi_lfric_tests/example_forecast/iodef.xml index 5af66f247..7a100a000 100644 --- a/applications/jedi_lfric_tests/example_forecast/iodef.xml +++ b/applications/jedi_lfric_tests/example_forecast/iodef.xml @@ -66,6 +66,8 @@ + + @@ -294,7 +296,7 @@ performance - 1.0 + 1.0 diff --git a/applications/jedi_lfric_tests/example_forecast_pseudo/configuration.nml b/applications/jedi_lfric_tests/example_forecast_pseudo/configuration.nml index 9447dfff7..f3a627297 100644 --- a/applications/jedi_lfric_tests/example_forecast_pseudo/configuration.nml +++ b/applications/jedi_lfric_tests/example_forecast_pseudo/configuration.nml @@ -10,7 +10,7 @@ forecast_length='P0DT6H0M0S', &jedi_geometry io_calender_start='2018-04-14T21:00:00', io_path_inc_read='', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.false., io_time_step='P0DT1H0M0S', @@ -52,6 +52,9 @@ element_order_h=0, element_order_v=0, rehabilitate=.true., / +&formulation +use_multires_coupling=.false., +/ &io file_convention='UGRID', / @@ -68,3 +71,12 @@ scaling_factor=1.0, &time calendar_type='gregorian', / +&transport +dep_pt_stencil_extent=3, +ffsl_inner_order=0, +ffsl_outer_order=1, +fv_horizontal_order=2, +operators='fv', +panel_edge_high_order=.false., +panel_edge_treatment='none', +/ diff --git a/applications/jedi_lfric_tests/example_forecast_pseudo/configuration_op.nml b/applications/jedi_lfric_tests/example_forecast_pseudo/configuration_op.nml index c179e76eb..e392cbdd7 100644 --- a/applications/jedi_lfric_tests/example_forecast_pseudo/configuration_op.nml +++ b/applications/jedi_lfric_tests/example_forecast_pseudo/configuration_op.nml @@ -10,7 +10,7 @@ forecast_length='P0DT6H0M0S', &jedi_geometry io_calender_start='2018-04-14T21:00:00', io_path_inc_read='', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.false., io_time_step='P0DT1H0M0S', diff --git a/applications/jedi_lfric_tests/example_forecast_pseudo/iodef.xml b/applications/jedi_lfric_tests/example_forecast_pseudo/iodef.xml index 6c7c230a2..5aade9f56 100644 --- a/applications/jedi_lfric_tests/example_forecast_pseudo/iodef.xml +++ b/applications/jedi_lfric_tests/example_forecast_pseudo/iodef.xml @@ -47,7 +47,7 @@ - + @@ -61,7 +61,7 @@ - + @@ -84,7 +84,7 @@ performance - 1.0 + 1.0 diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml index 53acee0fc..e1a1eca60 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/configuration.nml @@ -1,13 +1,10 @@ &jedi_lfric_tests test_field='theta', / - -#### Configure JEDI-LFRIC - &jedi_geometry io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.false., io_time_step='P0DT1H0M0S', @@ -15,8 +12,8 @@ io_time_step='P0DT1H0M0S', &jedi_state state_time='2018-04-14 21:00:00', use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', +'m_cl','m_r','m_s','land_fraction', / &jedi_increment inc_time='2018-04-14 21:00:00', @@ -34,21 +31,19 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings +adjoint_test_tolerance=1.0e-4, forecast_length='P0DT6H0M0S', / - -#### Configure LFRic - &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -70,6 +65,15 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, @@ -79,6 +83,7 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -96,7 +101,7 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', @@ -117,10 +122,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -130,27 +135,36 @@ shallow=.true., si_momentum_equation=.false., theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., +gcrk=8, +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, +preconditioner='multigrid', +si_pressure_a_tol=1.0e-8, +si_pressure_maximum_iterations=400, +si_pressure_tolerance=1.0e-4, +/ +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau / &idealised f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -174,7 +188,6 @@ coarse_ozone_ancil=.false., init_option='analytic', lbc_option='none', ls_option='analytic', -model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., sea_ice_source='ancillary', @@ -185,10 +198,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -200,7 +213,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -209,22 +222,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -237,26 +253,42 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., -pert_option='analytic', +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', +transport_efficiency=.true., +/ +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, +fail_on_non_converged=.true., +gcrk=4, guess_np1=.false., -mixed_solver_a_tol=1.0e-21, +mixed_solver_a_tol=1.0e-3, monitor_convergence=.true., normalise=.true., reference_reset_time=3600.0, -si_maximum_iterations=7, +si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', -si_tolerance=1.0e-21, +si_tolerance=1.0e-1, split_w=.true., / &mixing @@ -265,6 +297,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -272,15 +312,23 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +bl_segment=0, +configure_segments=.true., +conv_gr_segment=16, +gw_segment=0, limit_drag_incs=.false., +ls_ppn_segment=0, sample_physics_scalars=.true., sample_physics_winds=.true., +sample_physics_winds_correction=.false., +ussp_segment=0, / &planet cp=1005.0, @@ -292,10 +340,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -308,24 +360,27 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', vo_rad_opt='off', / &solver -fail_on_non_converged=.false., gcrk=18, -maximum_iterations=50, +maximum_iterations=7, method='chebyshev', monitor_convergence=.false., preconditioner='diagonal', -tolerance=1.0e-18, +tolerance=1.0e-6, +/ +&specified_surface / &time calendar='timestep', @@ -337,8 +392,8 @@ timestep_start='1', / ×tepping alpha=0.55, -dt=3600, -inner_iterations=2, +dt=1800, +inner_iterations=1, method='semi_implicit', outer_iterations=2, runge_kutta_method='forward_euler', @@ -349,10 +404,12 @@ tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_tracer_equation=.false., +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -362,43 +419,45 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false. -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', slice_order='parabola', +special_edges_monotone=5*1, splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml index 1de565f8b..4a65814b5 100644 --- a/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_id_tlm_tests/iodef.xml @@ -41,13 +41,14 @@ + - + @@ -55,13 +56,14 @@ + - + @@ -74,7 +76,7 @@ - + @@ -144,6 +146,11 @@ + + + + + @@ -234,6 +241,8 @@ + + @@ -280,6 +289,8 @@ + + @@ -396,7 +407,7 @@ - + @@ -421,6 +432,7 @@ + @@ -431,7 +443,7 @@ performance - 1.0 + 1.0 diff --git a/applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12.nc b/applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12_MG.nc similarity index 64% rename from applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12.nc rename to applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12_MG.nc index f7ea6988e..ebe518907 100644 Binary files a/applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12.nc and b/applications/jedi_lfric_tests/example_id_tlm_tests/mesh_C12_MG.nc differ diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml index f61e5aab0..3ea39dd10 100644 --- a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration.nml @@ -1,30 +1,28 @@ &jedi_lfric_tests test_field='theta', / - -#### Configure JEDI-LFRIC - &jedi_geometry io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', -io_setup_increment=.true., +io_setup_increment=.false., io_time_step='P0DT1H0M0S', / &jedi_state state_time='2018-04-14 21:00:00', use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', +'m_cl','m_r','m_s','land_fraction', / &jedi_increment inc_time='2018-04-14 21:00:00', -initialise_via_read=.true., +initialise_via_read=.false., variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', 'm_cl','m_r','m_s', / &jedi_linear_model +incremental_wind_interpolation=.false., nl_time_step='P0DT1H0M0S', / &jedi_pseudo_model @@ -33,21 +31,19 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings +adjoint_test_tolerance=1.0e-3, forecast_length='P0DT6H0M0S', / - -#### Configure LFRic - &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -69,6 +65,15 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, @@ -78,7 +83,7 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -96,7 +101,7 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', @@ -117,10 +122,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -128,29 +133,38 @@ p2theta_vert=.true., rotating=.true., shallow=.true., si_momentum_equation=.false., -theta_moist_source=.false. +theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., +gcrk=8, +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, +preconditioner='multigrid', +si_pressure_a_tol=1.0e-8, +si_pressure_maximum_iterations=400, +si_pressure_tolerance=1.0e-4, +/ +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau / &idealised f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -174,7 +188,6 @@ coarse_ozone_ancil=.false., init_option='analytic', lbc_option='none', ls_option='analytic', -model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., sea_ice_source='ancillary', @@ -185,10 +198,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -200,7 +213,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -209,22 +222,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -237,26 +253,42 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., -pert_option='analytic', +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', +transport_efficiency=.true., +/ +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, +fail_on_non_converged=.true., +gcrk=4, guess_np1=.false., mixed_solver_a_tol=1.0e-21, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=7, +reference_reset_time=1800, +si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', -si_tolerance=1.0e-21, +si_tolerance=1.0e-3, split_w=.true., / &mixing @@ -265,6 +297,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -272,15 +312,23 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +bl_segment=0, +configure_segments=.true., +conv_gr_segment=16, +gw_segment=0, limit_drag_incs=.false., +ls_ppn_segment=0, sample_physics_scalars=.true., sample_physics_winds=.true., +sample_physics_winds_correction=.false., +ussp_segment=0, / &planet cp=1005.0, @@ -292,10 +340,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -308,24 +360,27 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', vo_rad_opt='off', / &solver -fail_on_non_converged=.false., gcrk=18, -maximum_iterations=50, +maximum_iterations=7, method='chebyshev', monitor_convergence=.false., preconditioner='diagonal', -tolerance=1.0e-18, +tolerance=1.0e-6, +/ +&specified_surface / &time calendar='timestep', @@ -337,10 +392,10 @@ timestep_start='1', / ×tepping alpha=0.55, -dt=3600, -inner_iterations=2, +dt=1800, +inner_iterations=1, method='semi_implicit', -outer_iterations=2, +outer_iterations=1, runge_kutta_method='forward_euler', spinup_alpha=.false., tau_r=1.0, @@ -349,10 +404,12 @@ tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_tracer_equation=.false., +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -362,28 +419,29 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false., -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', @@ -393,13 +451,13 @@ splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration_op.nml b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration_op.nml index 7b9d54bf3..f472b5066 100644 --- a/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration_op.nml +++ b/applications/jedi_lfric_tests/example_tlm_forecast_tl/configuration_op.nml @@ -6,8 +6,8 @@ test_field='theta', &jedi_geometry io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.true., io_time_step='P0DT1H0M0S', @@ -96,7 +96,7 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', @@ -345,6 +345,7 @@ tau_u=0.55, / &transport adjust_theta=.false., +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false., calculate_detj='upwind', diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/iodef.xml b/applications/jedi_lfric_tests/example_tlm_forecast_tl/iodef.xml index 1de565f8b..4a65814b5 100644 --- a/applications/jedi_lfric_tests/example_tlm_forecast_tl/iodef.xml +++ b/applications/jedi_lfric_tests/example_tlm_forecast_tl/iodef.xml @@ -41,13 +41,14 @@ + - + @@ -55,13 +56,14 @@ + - + @@ -74,7 +76,7 @@ - + @@ -144,6 +146,11 @@ + + + + + @@ -234,6 +241,8 @@ + + @@ -280,6 +289,8 @@ + + @@ -396,7 +407,7 @@ - + @@ -421,6 +432,7 @@ + @@ -431,7 +443,7 @@ performance - 1.0 + 1.0 diff --git a/applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12.nc b/applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12_MG.nc similarity index 64% rename from applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12.nc rename to applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12_MG.nc index f7ea6988e..ebe518907 100644 Binary files a/applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12.nc and b/applications/jedi_lfric_tests/example_tlm_forecast_tl/mesh_C12_MG.nc differ diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml index 283c5dafb..da9b864b8 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml +++ b/applications/jedi_lfric_tests/example_tlm_tests/configuration.nml @@ -1,13 +1,10 @@ &jedi_lfric_tests test_field='theta', / - -#### Configure JEDI-LFRIC - &jedi_geometry io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', +io_path_inc_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', +io_path_state_read='/data/users/lfricadmin/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', io_path_state_write='write_file', io_setup_increment=.false., io_time_step='P0DT1H0M0S', @@ -15,8 +12,8 @@ io_time_step='P0DT1H0M0S', &jedi_state state_time='2018-04-14 21:00:00', use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', +'m_cl','m_r','m_s','land_fraction', / &jedi_increment inc_time='2018-04-14 21:00:00', @@ -25,7 +22,7 @@ variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', 'm_cl','m_r','m_s', / &jedi_linear_model -incremental_wind_interpolation=.true., +incremental_wind_interpolation=.false., nl_time_step='P0DT1H0M0S', / &jedi_pseudo_model @@ -34,21 +31,19 @@ number_of_steps=9, time_step='P0DT1H0M0S', / &jedi_lfric_settings +adjoint_test_tolerance=1.0e-2, forecast_length='P0DT6H0M0S', / - -#### Configure LFRic - &base_mesh -file_prefix='mesh_C12', +file_prefix='mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -70,6 +65,15 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, @@ -79,7 +83,7 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, -share_stencil_extent=.true. +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -97,7 +101,7 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', diag_stem_name='', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', @@ -118,10 +122,10 @@ dlayer_on=.true., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., moisture_formulation='traditional', moisture_in_solver=.true., @@ -129,29 +133,38 @@ p2theta_vert=.true., rotating=.true., shallow=.true., si_momentum_equation=.false., -theta_moist_source=.false. +theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., +gcrk=8, +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, +preconditioner='multigrid', +si_pressure_a_tol=1.0e-8, +si_pressure_maximum_iterations=400, +si_pressure_tolerance=1.0e-4, +/ +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau / &idealised f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -175,7 +188,6 @@ coarse_ozone_ancil=.false., init_option='analytic', lbc_option='none', ls_option='analytic', -model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., sea_ice_source='ancillary', @@ -186,10 +198,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -201,7 +213,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -210,22 +222,25 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / &io checkpoint_read=.false., +checkpoint_times=, checkpoint_write=.false., counter_output_suffix='counter.txt', diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, +end_of_run_checkpoint=.true., file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., @@ -238,26 +253,42 @@ write_fluxes=.false., write_minmax_tseries=.false., / &linear -fixed_ls=.true. +fixed_ls=.true., +l_stabilise_bl=.false., ls_read_w2h=.false., -pert_option='analytic', +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', +transport_efficiency=.true., +/ +&linear_physics +blevs_m=15, +e_folding_levs_m=10, +l_0_m=80.0, +l_boundary_layer=.true., +log_layer=2, +u_land_m=0.4, +u_sea_m=0.4, +z_land_m=0.05, +z_sea_m=0.0005, / &logging +log_to_rank_zero_only=.false., run_log_level='info', / &mixed_solver eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, +fail_on_non_converged=.true., +gcrk=4, guess_np1=.false., mixed_solver_a_tol=1.0e-21, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=7, +reference_reset_time=1800, +si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', -si_tolerance=1.0e-21, +si_tolerance=1.0e-3, split_w=.true., / &mixing @@ -266,6 +297,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -273,15 +312,23 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', panel_xproc=1, panel_yproc=1, partitioner='cubedsphere', / &physics +bl_segment=0, +configure_segments=.true., +conv_gr_segment=16, +gw_segment=0, limit_drag_incs=.false., +ls_ppn_segment=0, sample_physics_scalars=.true., sample_physics_winds=.true., +sample_physics_winds_correction=.false., +ussp_segment=0, / &planet cp=1005.0, @@ -293,10 +340,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -309,24 +360,27 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', vo_rad_opt='off', / &solver -fail_on_non_converged=.false., gcrk=18, -maximum_iterations=50, +maximum_iterations=7, method='chebyshev', monitor_convergence=.false., preconditioner='diagonal', -tolerance=1.0e-18, +tolerance=1.0e-6, +/ +&specified_surface / &time calendar='timestep', @@ -338,10 +392,10 @@ timestep_start='1', / ×tepping alpha=0.55, -dt=3600, -inner_iterations=2, +dt=1800, +inner_iterations=1, method='semi_implicit', -outer_iterations=2, +outer_iterations=1, runge_kutta_method='forward_euler', spinup_alpha=.false., tau_r=1.0, @@ -350,10 +404,12 @@ tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_tracer_equation=.false., +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -363,28 +419,29 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', +log_space=.true.,.true.,.false.,.false.,.false., +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', -panel_edge_high_order=.false., -panel_edge_treatment='none' +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, -reversible=5*.false., +reversible=.true.,.true.,.false.,.true.,.true., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', @@ -394,13 +451,13 @@ splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml b/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml deleted file mode 100644 index c9b945825..000000000 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry.nml +++ /dev/null @@ -1,404 +0,0 @@ -&jedi_lfric_tests -test_field='theta', -/ - -#### Configure JEDI-LFRIC - -&jedi_geometry -io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', -io_path_state_write='write_file', -io_setup_increment=.false., -io_time_step='P0DT1H0M0S', -/ -&jedi_state -state_time='2018-04-14 21:00:00', -use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', -/ -&jedi_increment -inc_time='2018-04-14 21:00:00', -initialise_via_read=.false., -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', -'m_cl','m_r','m_s', -/ -&jedi_linear_model -incremental_wind_interpolation=.true., -nl_time_step='P0DT1H0M0S', -/ -&jedi_pseudo_model -initial_time='2018-04-14T21:00:00', -number_of_steps=9, -time_step='P0DT1H0M0S', -/ -&jedi_lfric_settings -forecast_length='P0DT6H0M0S', -/ - -#### Configure LFRic - -&base_mesh -file_prefix='mesh_C12', -geometry='spherical', -prepartitioned=.false., -prime_mesh_name='C12', -topology='fully_periodic', -/ -&boundaries -limited_area=.false., -transport_overwrite_freq='final' -/ -&checks -limit_cfl=.false., -/ -§ion_choice -aerosol='none', -boundary_layer='none', -chemistry='none', -cloud='none', -dynamics='gungho', -external_forcing=.false., -iau=.false., -iau_sst=.false., -iau_surf=.false., -methane_oxidation=.false., -orographic_drag='none', -radiation='none', -spectral_gwd='none', -stochastic_physics='none', -surface='none', -/ -&damping_layer -dl_base=40000.0, -dl_str=0.05, -dl_type='standard', -/ -&departure_points -horizontal_limit='cap', -horizontal_method='ffsl', -n_dep_pt_iterations=1, -vertical_limit='exponential', -vertical_method='timeaverage', -vertical_sorting=.false., -/ -&energy_correction -encorr_usage='none', -integral_method='fd', -/ -&extrusion -domain_height=80000.0, -method='um_L70_50t_20s_80km', -number_of_layers=70, -planet_radius=6371229.0, -stretching_height=17507.0, -stretching_method='smooth', -/ -&files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', -checkpoint_stem_name='', -diag_stem_name='', -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', -/ -&finite_element -cellshape='quadrilateral', -coord_order=1, -coord_system='native', -element_order_h=0, -element_order_v=0, -rehabilitate=.true., -vorticity_in_w1=.false., -/ -&formulation -dlayer_on=.true., -dry_static_adjust=.true., -eos_method='sampled', -exner_from_eos=.false., -horizontal_physics_predictor=.false. -horizontal_transport_predictor=.false. -init_exner_bt=.true., -l_multigrid=.false., -lagged_orog=.true., -moisture_formulation='dry', -moisture_in_solver=.false., -p2theta_vert=.true., -rotating=.true., -shallow=.true., -si_momentum_equation=.false., -use_multires_coupling=.false., -use_physics=.false., -use_wavedynamics=.true., -vector_invariant=.false., -/ -&helmholtz_solver -fail_on_non_converged=.false., -gcrk=18, -method='bicgstab', -monitor_convergence=.true., -normalise=.true., -preconditioner='tridiagonal', -si_pressure_a_tol=0, -si_pressure_maximum_iterations=40, -si_pressure_tolerance=1.0e-15, -/ -&idealised -f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', -/ -&ideal_surface -canopy_height=19.01,16.38,0.79,1.26,1.0, -leaf_area_index=5.0,4.0,1.5,1.5,1.5, -n_snow_layers=11*0, -snow_depth=11*0.0, -snow_layer_ice_mass=27*0.0, -snow_layer_temp=27*273.0, -snow_layer_thickness=27*0.0, -soil_moisture=15.86,98.861,274.35,862.27, -soil_temperature=284.508,286.537,289.512,293.066, -surf_tile_fracs=9*0.0,1.0,0.0, -surf_tile_temps=9*295.0,300.0,265.0, -tile_snow_mass=11*0.0, -/ -&initialization -ancil_option='none', -coarse_aerosol_ancil=.false., -coarse_orography_ancil=.false., -coarse_ozone_ancil=.false., -init_option='analytic', -lbc_option='none', -ls_option='analytic', -model_eos_height=100, -n_orog_smooth=0, -read_w2h_wind=.true., -sea_ice_source='ancillary', -snow_source='start_dump', -w0_orography_mapping=.false., -zero_w2v_wind=.false., -/ -&initial_density -density_background=0.1, -density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, -y1=0.0, -y2=0.0, -z1=0.0, -z2=0.0, -/ -&initial_pressure -method='balanced', -surface_pressure=1000.0e2, -/ -&initial_temperature -bvf_square=0.0001, -pert_centre=120.0, -pert_width_scaling=1.0, -perturb='none', -theta_surf=300.0, -/ -&initial_vapour -/ -&initial_wind -nl_constant=0.0, -profile='none', -sbr_angle_lat=0.0, -sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, -v0=0.0, -wind_time_period=0.0, -/ -&io -checkpoint_read=.false., -checkpoint_write=.false., -counter_output_suffix='counter.txt', -diag_active_files='lfric_diag', -diag_always_on_sampling=.false., -diagnostic_frequency=8, -file_convention='UGRID', -nodal_output_on_w3=.false., -subroutine_counters=.false., -subroutine_timers=.true., -timer_output_path='timer.txt', -use_xios_io=.true., -write_conservation_diag=.false., -write_diag=.true., -write_dump=.false., -write_fluxes=.false., -write_minmax_tseries=.false., -/ -&linear -fixed_ls=.true. -ls_read_w2h=.false., -pert_option='analytic', -/ -&logging -run_log_level='info', -/ -&mixed_solver -eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=10, -guess_np1=.false., -mixed_solver_a_tol=1.0e-21, -monitor_convergence=.true., -normalise=.true., -reference_reset_time=3600.0, -si_maximum_iterations=7, -si_method='block_gcr', -si_preconditioner='pressure', -si_tolerance=1.0e-21, -split_w=.true., -/ -&mixing -leonard_term=.false., -smagorinsky=.false., -viscosity=.false., -viscosity_mu=0.0, -/ -&esm_couple -l_esm_couple_test=.false., -/ -&orography -orog_init_option='ancil', -/ -&partitioning -panel_decomposition='auto', -panel_xproc=1, -panel_yproc=1, -partitioner='cubedsphere', -/ -&physics -limit_drag_incs=.false., -sample_physics_scalars=.true., -sample_physics_winds=.true., -/ -&planet -cp=1005.0, -gravity=9.80665, -omega=7.292116E-5, -p_zero=100000.0, -rd=287.05, -scaling_factor=1.0, -/ -&radiative_gases -cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', -co_rad_opt='off', -cs_rad_opt='off', -h2_rad_opt='off', -h2o_rad_opt='prognostic', -hcfc22_rad_opt='off', -hcn_rad_opt='off', -he_rad_opt='off', -hfc134a_rad_opt='off', -k_rad_opt='off', -l_cts_fcg_rates=.false., -li_rad_opt='off', -n2_rad_opt='off', -n2o_rad_opt='off', -na_rad_opt='off', -nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', -rb_rad_opt='off', -so2_rad_opt='off', -tio_rad_opt='off', -vo_rad_opt='off', -/ -&solver -fail_on_non_converged=.false., -gcrk=18, -maximum_iterations=50, -method='chebyshev', -monitor_convergence=.false., -preconditioner='diagonal', -tolerance=1.0e-18, -/ -&time -calendar='timestep', -calendar_origin='2018-04-14 21:00:00', -calendar_start='2018-04-14 21:00:00', -calendar_type='gregorian', -timestep_end='13', -timestep_start='1', -/ -×tepping -alpha=0.55, -dt=3600, -inner_iterations=2, -method='semi_implicit', -outer_iterations=2, -runge_kutta_method='forward_euler', -spinup_alpha=.false., -tau_r=1.0, -tau_t=1.0, -tau_u=0.55, -/ -&transport -adjust_theta=.false., -adjust_vhv_wind=.false. -broken_w2_projection=.false., -calculate_detj='upwind', -cap_density_predictor=0.01, -cfl_mol_1d_stab=1.0, -cfl_mol_2d_stab=1.0, -cfl_mol_3d_stab=1.0, -cheap_update=.false., -consistent_metric=.false., -dep_pt_stencil_extent=3, -dry_field_name='density', -enforce_min_value=5*.false., -equation_form=1,2,2,2,2, -extended_mesh=.false., -ffsl_inner_order=2, -ffsl_outer_order=2, -ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', -fv_horizontal_order=2, -fv_vertical_order=2, -horizontal_method=5*1, -horizontal_monotone=5*1, -log_space=5*.false., -max_vert_cfl_calc='uniform', -min_val_abs_tol=-1.0e-12, -min_val_max_iterations=10, -min_val_method='iterative', -min_value=0.0,0.0,-99999999.0,0.0,0.0, -oned_reconstruction=.false., -operators='fv', -profile_size=5, -reversible=5*.false., -runge_kutta_method='ssp3', -scheme=5*1, -si_outer_transport='none', -slice_order='parabola', -splitting=5*1, -substep_transport='off', -theta_dispersion_correction=.false., -theta_variable='dry', -use_density_predictor=.false., -vertical_method=5*1, -vertical_monotone=5*1, -vertical_monotone_order=5*1, -vertical_sl_order='cubic', -wind_mono_top=.false. -wind_mono_top_depth=5 -/ -&validity_test -number_gamma_values=2, -update_ls_frequency=1, -/ diff --git a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml index 1de565f8b..4a65814b5 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml +++ b/applications/jedi_lfric_tests/example_tlm_tests/iodef.xml @@ -41,13 +41,14 @@ + - + @@ -55,13 +56,14 @@ + - + @@ -74,7 +76,7 @@ - + @@ -144,6 +146,11 @@ + + + + + @@ -234,6 +241,8 @@ + + @@ -280,6 +289,8 @@ + + @@ -396,7 +407,7 @@ - + @@ -421,6 +432,7 @@ + @@ -431,7 +443,7 @@ performance - 1.0 + 1.0 diff --git a/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12.nc b/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12.nc deleted file mode 100644 index f7ea6988e..000000000 Binary files a/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12.nc and /dev/null differ diff --git a/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12_MG.nc b/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12_MG.nc new file mode 100644 index 000000000..ebe518907 Binary files /dev/null and b/applications/jedi_lfric_tests/example_tlm_tests/mesh_C12_MG.nc differ diff --git a/applications/jedi_lfric_tests/integration-test/algorithm/algorithm_test.f90 b/applications/jedi_lfric_tests/integration-test/algorithm/algorithm_test.f90 index 9748e3f94..a62b68ecb 100644 --- a/applications/jedi_lfric_tests/integration-test/algorithm/algorithm_test.f90 +++ b/applications/jedi_lfric_tests/integration-test/algorithm/algorithm_test.f90 @@ -69,7 +69,7 @@ program algorithm_test logical(l_def) :: apply_partition_check integer(i_def) :: geometry - integer(i_def) :: stencil_depth + integer(i_def) :: stencil_depth(1) integer(i_def) :: method integer(i_def) :: number_of_layers real(r_def) :: domain_bottom diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf index 683dc9533..57cab669b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/HEAD/rose-meta.conf @@ -52,6 +52,14 @@ help=Configuration option for JEDI-LFRIC emulator. ns=namelist/JEDI-LFRIC-setup title=JEDI-LFRIC Setings +[namelist:jedi_lfric_settings=adjoint_test_tolerance] +compulsory=false +description=Tolerance for inner product adjoint tests in jedi_tlm_tests +help=Set as appropriate based on configuration +!kind=default +sort-key= +type=real + [namelist:jedi_lfric_settings=forecast_length] compulsory=true description=The forecast duration diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/version30_31.py b/applications/jedi_lfric_tests/rose-meta/jedi_common/version30_31.py new file mode 100644 index 000000000..8d220cefa --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/version30_31.py @@ -0,0 +1,300 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t132(MacroUpgrade): + """Upgrade macro for ticket #132 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jedi_common + self.add_setting( + config, + ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], + "1.0e-4", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t132" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_common + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_common/vn3.1/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_common/vn3.1/rose-meta.conf new file mode 100644 index 000000000..d8596029b --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_common/vn3.1/rose-meta.conf @@ -0,0 +1,158 @@ +import=lfric-adjoint/vn3.1 + +#============================================================================== +# Geometry for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_geometry] +compulsory=true +description=JEDI-LFRIC emulator geometry configuration +help=Configuration options for JEDI-LFRIC emulator geometry object. +ns=namelist/JEDI-LFRIC-setup/jedi_geometry +title=jedi_geometry + +[namelist:jedi_geometry=io_calender_start] +compulsory=true +description=The IO clock start date +help=Format: yyyy-mm-ddThh:mm:ss +!kind=default +sort-key= +type=character + +[namelist:jedi_geometry=io_path_state_read] +compulsory=true +description=Path to the file to be read +help=This is the lfric_diag.nc file which stores a test trajectory (set of states) +!kind=default +sort-key= +type=character + +[namelist:jedi_geometry=io_path_state_write] +compulsory=true +description=Path to the file that will be written +help=This is the file that will be written to +!kind=default +sort-key= +type=character + +[namelist:jedi_geometry=io_time_step] +compulsory=true +description=The time step duration +help=Format: PdDThHmMsS where d=day, h=hours, m=minutes and s=seconds +!kind=default +sort-key= +type=character + +#============================================================================== +# Setup for the JEDI-LFRIC Emulator application +#============================================================================== +[namelist:jedi_lfric_settings] +compulsory=true +description=JEDI-LFRIC emulator application configuration +help=Configuration option for JEDI-LFRIC emulator. +ns=namelist/JEDI-LFRIC-setup +title=JEDI-LFRIC Setings + +[namelist:jedi_lfric_settings=adjoint_test_tolerance] +compulsory=false +description=Tolerance for inner product adjoint tests in jedi_tlm_tests +help=Set as appropriate based on configuration +!kind=default +sort-key= +type=real + +[namelist:jedi_lfric_settings=forecast_length] +compulsory=true +description=The forecast duration +help=Format: PdDThHmMsS where d=day, h=hours, m=minutes and s=seconds +!kind=default +sort-key= +type=character + +#============================================================================== +# jedi_lfric_tests for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_lfric_tests] +compulsory=true +description= +ns=namelist/jedi_lfric_tests +title=jedi_lfric_tests + +[namelist:jedi_lfric_tests=test_field] +compulsory=true +description=Which field to apply the algorithm to +help=One of the jedi_lfric_tests fields should contain distinct data for test purposes +!kind=default +sort-key= +type=character + +#============================================================================== +# Pseudo model for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_pseudo_model] +compulsory=true +description=JEDI-LFRIC emulator pseudo model configuration +help=Configuration options for JEDI-LFRIC emulator pseudo model object. +ns=namelist/JEDI-LFRIC-setup/jedi_pseudo_model +title=jedi_pseudo_model + +[namelist:jedi_pseudo_model=initial_time] +compulsory=true +description=The start date for the the model run +help=Add the start date for the the model run + =Format: yyyy-mm-ddThh:mm:ss +!kind=default +sort-key= +type=character + +[namelist:jedi_pseudo_model=number_of_steps] +compulsory=true +description=The number of time steps to run +help=Add the number of time steps +!kind=default +sort-key= +type=integer + +[namelist:jedi_pseudo_model=time_step] +compulsory=true +description=The model time step duration +help=Format PdDThHmMsS where d=day, h=hours, m=minutes and s=seconds +!kind=default +sort-key= +type=character + +#============================================================================== +# State for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_state] +compulsory=true +description=JEDI-LFRIC emulator state configuration +help=Configuration options for JEDI-LFRIC emulator state object. +ns=namelist/JEDI-LFRIC-setup/jedi_state +title=jedi_state + +[namelist:jedi_state=state_time] +compulsory=true +description=The validity date of the state +help=Format: yyyy-mm-dd hh:mm:ss +!kind=default +sort-key= +type=character + +[namelist:jedi_state=use_pseudo_model] +compulsory=true +description=A logical that defines how the state should be setup +help=A logical that when true sets the state up to be used + =with the pseudo model. This means NL model modeldb + =is not instantiated +!kind=default +sort-key= +type=logical + +[namelist:jedi_state=variables] +compulsory=true +description=List of variables to be instantiated +help=Add a comma separted list of variables to instantiate + =format: 'theta', 'rho', ... +length=: +sort-key= +type=character diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_forecast/version30_31.py b/applications/jedi_lfric_tests/rose-meta/jedi_forecast/version30_31.py new file mode 100644 index 000000000..298dcf28c --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_forecast/version30_31.py @@ -0,0 +1,302 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t132(MacroUpgrade): + """Upgrade macro for ticket #132 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jedi_common + self.add_setting( + config, + ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], + "1.0e-4", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t132" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_common + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_forecast + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_forecast/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_forecast/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_forecast/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_forecast/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_forecast/vn3.1/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_forecast/vn3.1/rose-meta.conf new file mode 100644 index 000000000..d191bf9f1 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_forecast/vn3.1/rose-meta.conf @@ -0,0 +1,18 @@ +import=jedi_common/vn3.1 + +#============================================================================== +# Model for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_model] +compulsory=true +description=Jedi model configuration +ns=namelist/JEDI-LFRIC-setup/jedi_model +title=jedi_model + +[namelist:jedi_model=time_step] +compulsory=true +description=The models time step duration +help=Format PdDThHmMsS where d=day, h=hours, m=minutes and s=seconds +!kind=default +sort-key= +type=character diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/version30_31.py b/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/version30_31.py new file mode 100644 index 000000000..76f100e30 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/version30_31.py @@ -0,0 +1,302 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t132(MacroUpgrade): + """Upgrade macro for ticket #132 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jedi_common + self.add_setting( + config, + ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], + "1.0e-4", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t132" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_common + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_forecast_pseudo + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/vn3.1/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/vn3.1/rose-meta.conf new file mode 100644 index 000000000..8dd6d6593 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_forecast_pseudo/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=jedi_common/vn3.1 diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/version30_31.py b/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/version30_31.py new file mode 100644 index 000000000..8307c6c78 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/version30_31.py @@ -0,0 +1,302 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t132(MacroUpgrade): + """Upgrade macro for ticket #132 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jedi_common + self.add_setting( + config, + ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], + "1.0e-4", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t132" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_common + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_id_tlm_tests + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/vn3.1/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/vn3.1/rose-meta.conf new file mode 100644 index 000000000..d278ae7ff --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_id_tlm_tests/vn3.1/rose-meta.conf @@ -0,0 +1,28 @@ +import=jedi_common/vn3.1 + +#============================================================================== +# Increment for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_increment] +compulsory=true +description=JEDI-LFRIC emulator increment configuration +help=Configuration options for JEDI-LFRIC emulator increment object. +ns=namelist/JEDI-LFRIC-setup/jedi_increment +title=jedi_increment + +[namelist:jedi_increment=inc_time] +compulsory=true +description=The validity date of the increment +help=Format: yyyy-mm-dd hh:mm:ss +!kind=default +sort-key= +type=character + +[namelist:jedi_increment=variables] +compulsory=true +description=List of variables to be instantiated +help=Add a comma separted list of variables to instantiate + =format: 'theta', 'rho', ... +length=: +sort-key= +type=character diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/version30_31.py b/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/version30_31.py new file mode 100644 index 000000000..9924ff413 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/version30_31.py @@ -0,0 +1,302 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t132(MacroUpgrade): + """Upgrade macro for ticket #132 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jedi_common + self.add_setting( + config, + ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], + "1.0e-4", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t132" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_common + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_lfric_tests + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/vn3.1/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/vn3.1/rose-meta.conf new file mode 100644 index 000000000..f19808878 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_lfric_tests/vn3.1/rose-meta.conf @@ -0,0 +1,93 @@ +import=jedi_common/vn3.1 + +[namelist:jedi_geometry=io_path_inc_read] +compulsory=true +description=File to read the linear model increment from +help=This is the initial condition increment file +!kind=default +sort-key= +type=character + +[namelist:jedi_geometry=io_setup_increment] +compulsory=true +description=Setup setup increment file +help=The increment file defined by io_path_inc_read will be setup if true +!kind=default +sort-key= +type=logical + +#============================================================================== +# Increment for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_increment] +compulsory=true +description=JEDI-LFRIC emulator increment configuration +help=Configuration options for JEDI-LFRIC emulator increment object. +ns=namelist/JEDI-LFRIC-setup/jedi_increment +title=jedi_increment + +[namelist:jedi_increment=inc_time] +compulsory=true +description=The validity date of the increment +help=Format: yyyy-mm-dd hh:mm:ss +!kind=default +sort-key= +type=character + +[namelist:jedi_increment=initialise_via_read] +compulsory=true +description=Initialise increment via read +help=The increment will be setup via file read if true +!kind=default +sort-key= +type=logical + +[namelist:jedi_increment=variables] +compulsory=true +description=List of variables to be instantiated +help=Add a comma separted list of variables to instantiate + =format: 'theta', 'rho', ... +length=: +sort-key= +type=character + +#============================================================================== +# Linear Model for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_linear_model] +compulsory=true +description=Jedi linear-model configuration +ns=namelist/JEDI-LFRIC-setup/jedi_linear_model +title=jedi_linear_model + +[namelist:jedi_linear_model=incremental_wind_interpolation] +compulsory=true +description=Flag to control whether winds are interpolated incrementally +!kind=default +sort-key= +type=logical + +[namelist:jedi_linear_model=nl_time_step] +compulsory=true +description=The time step duration of the non-linear model +help=Format PdDThHmMsS where d=day, h=hours, m=minutes and s=seconds +!kind=default +sort-key= +type=character + +#============================================================================== +# Model for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_model] +compulsory=true +description=Jedi model configuration +ns=namelist/JEDI-LFRIC-setup/jedi_model +title=jedi_model + +[namelist:jedi_model=time_step] +compulsory=true +description=The models time step duration +help=Format PdDThHmMsS where d=day, h=hours, m=minutes and s=seconds +!kind=default +sort-key= +type=character diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/version30_31.py b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/version30_31.py new file mode 100644 index 000000000..e4395c289 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/version30_31.py @@ -0,0 +1,302 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t132(MacroUpgrade): + """Upgrade macro for ticket #132 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jedi_common + self.add_setting( + config, + ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], + "1.0e-4", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t132" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_common + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_tlm_forecast_tl + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/vn3.1/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/vn3.1/rose-meta.conf new file mode 100644 index 000000000..d278ae7ff --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_forecast_tl/vn3.1/rose-meta.conf @@ -0,0 +1,28 @@ +import=jedi_common/vn3.1 + +#============================================================================== +# Increment for the JEDI-LFRIC Emulator +#============================================================================== +[namelist:jedi_increment] +compulsory=true +description=JEDI-LFRIC emulator increment configuration +help=Configuration options for JEDI-LFRIC emulator increment object. +ns=namelist/JEDI-LFRIC-setup/jedi_increment +title=jedi_increment + +[namelist:jedi_increment=inc_time] +compulsory=true +description=The validity date of the increment +help=Format: yyyy-mm-dd hh:mm:ss +!kind=default +sort-key= +type=character + +[namelist:jedi_increment=variables] +compulsory=true +description=List of variables to be instantiated +help=Add a comma separted list of variables to instantiate + =format: 'theta', 'rho', ... +length=: +sort-key= +type=character diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf index 57a38b5b9..7f4050279 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/HEAD/rose-meta.conf @@ -1,8 +1,5 @@ import=jedi_common/HEAD -#============================================================================== -# Increment for the JEDI-LFRIC Emulator -#============================================================================== [namelist:jedi_increment] compulsory=true description=JEDI-LFRIC emulator increment configuration diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/version30_31.py b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/version30_31.py new file mode 100644 index 000000000..d661801d8 --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/version30_31.py @@ -0,0 +1,302 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t132(MacroUpgrade): + """Upgrade macro for ticket #132 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t132" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jedi_common + self.add_setting( + config, + ["namelist:jedi_lfric_settings", "adjoint_test_tolerance"], + "1.0e-4", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t132" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_common + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_tlm_tests + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/versions.py b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/versions.py +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/vn3.1/rose-meta.conf b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/vn3.1/rose-meta.conf new file mode 100644 index 000000000..9a6cbe17d --- /dev/null +++ b/applications/jedi_lfric_tests/rose-meta/jedi_tlm_tests/vn3.1/rose-meta.conf @@ -0,0 +1,25 @@ +import=jedi_common/vn3.1 + +[namelist:jedi_increment] +compulsory=true +description=JEDI-LFRIC emulator increment configuration +help=Configuration options for JEDI-LFRIC emulator increment object. +ns=namelist/JEDI-LFRIC-setup/jedi_increment +title=jedi_increment + +[namelist:jedi_increment=inc_time] +compulsory=true +description=The validity date of the increment +help=Format: yyyy-mm-dd hh:mm:ss +!kind=default +sort-key= +type=character + +[namelist:jedi_increment=variables] +compulsory=true +description=List of variables to be instantiated +help=Add a comma separted list of variables to instantiate + =format: 'theta', 'rho', ... +length=: +sort-key= +type=character diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_geometry_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_geometry_mod.f90 index 4fd1b473b..bebc16e4e 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_geometry_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_geometry_mod.f90 @@ -94,7 +94,6 @@ module jedi_geometry_mod !> subroutine initialise( self, mpi_comm, configuration ) ! Access config directly until modeldb ready - use driver_mesh_mod, only: init_mesh use driver_config_mod, only: init_config use jedi_lfric_mesh_setup_mod, only: initialise_mesh use jedi_lfric_tests_mod, only: jedi_lfric_tests_required_namelists diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 index 4cf75379e..2cc8af089 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_id_linear_model_mod.f90 @@ -34,6 +34,7 @@ module jedi_id_linear_model_mod use jedi_base_linear_model_mod, only : jedi_base_linear_model_type use jedi_lfric_duration_mod, only : jedi_duration_type use jedi_lfric_linear_fields_mod, only : variable_names, & + ls_variable_names, & create_linear_fields use jedi_lfric_wind_fields_mod, only : create_scalar_winds, & setup_vector_wind @@ -184,10 +185,10 @@ subroutine set_trajectory( self, jedi_state ) ! Create field collection that contains the linear state fields ! without "ls_" prepended. - call create_linear_fields(jedi_state%geometry%get_mesh(), next_linear_state) + call create_linear_fields(jedi_state%geometry%get_mesh(), jedi_state%geometry%get_twod_mesh(), next_linear_state) ! Copy data from the input state into next_linear_state - call jedi_state%get_to_field_collection( variable_names, & + call jedi_state%get_to_field_collection( ls_variable_names, & next_linear_state ) ! Create W2 wind, interpolate from scaler winds (W3/Wtheta) then diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 index 6be770327..797201121 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_linear_model_mod.f90 @@ -39,6 +39,7 @@ module jedi_linear_model_mod zero_moist_fields use jedi_lfric_duration_mod, only : jedi_duration_type use jedi_lfric_linear_fields_mod, only : variable_names, & + ls_variable_names, & create_linear_fields use jedi_lfric_wind_fields_mod, only : create_scalar_winds, & setup_vector_wind @@ -182,10 +183,10 @@ subroutine set_trajectory( self, jedi_state ) ! Create field collection that contains the linear state fields ! without "ls_" prepended. - call create_linear_fields(jedi_state%geometry%get_mesh(), next_linear_state) + call create_linear_fields(jedi_state%geometry%get_mesh(), jedi_state%geometry%get_twod_mesh(), next_linear_state) ! Copy data from the input state into next_linear_state - call jedi_state%get_to_field_collection( variable_names, & + call jedi_state%get_to_field_collection( ls_variable_names, & next_linear_state ) ! Create W2 wind, interpolate from scaler winds (W3/Wtheta) then diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_run_mod.f90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_run_mod.f90 index 8e981a2e9..b1597fc4a 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_run_mod.f90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_run_mod.f90 @@ -90,7 +90,9 @@ subroutine initialise_infrastructure( self, filename, model_communicator ) use driver_collections_mod, only: init_collections use driver_config_mod, only: init_config use driver_log_mod, only: init_logger - use driver_timer_mod, only: init_timers + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing + use io_config_mod, only: timer_output_path use jedi_lfric_tests_mod, only: jedi_lfric_tests_required_namelists use lfric_mpi_mod, only: lfric_comm_type @@ -101,6 +103,9 @@ subroutine initialise_infrastructure( self, filename, model_communicator ) integer(i_def), intent(in) :: model_communicator type(lfric_comm_type) :: lfric_comm + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + ! Initialise the configuration call self%configuration%initialise( self%jedi_run_name, table_len=10 ) @@ -116,8 +121,10 @@ subroutine initialise_infrastructure( self, filename, model_communicator ) call lfric_comm%set_comm_mpi_val(model_communicator) call init_logger( lfric_comm, self%jedi_run_name ) - ! Initialise subroutine timers - call init_timers( self%jedi_run_name ) + ! Initialise timing wrapper + io_nml => self%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( lfric_comm, lsubroutine_timers, trim(self%jedi_run_name), timer_output_path ) self%timers_finalised = .false. ! Initialise collections @@ -141,13 +148,13 @@ end function get_configuration !> subroutine finalise_timers(self) - use driver_timer_mod, only: final_timers + use timing_mod, only: final_timing implicit none class(jedi_run_type), intent(inout) :: self - call final_timers( self%jedi_run_name ) + call final_timing( self%jedi_run_name ) self%timers_finalised = .true. end subroutine finalise_timers @@ -159,7 +166,7 @@ subroutine finalise(self) use driver_collections_mod, only: final_collections use driver_config_mod, only: final_config use driver_log_mod, only: final_logger - use driver_timer_mod, only: final_timers + use timing_mod, only: final_timing use jedi_lfric_comm_mod, only: final_external_comm, & final_internal_comm use lfric_mpi_mod, only: destroy_comm @@ -172,7 +179,7 @@ subroutine finalise(self) call final_collections() ! Finalise subroutine timers - if (.not. self%timers_finalised) call final_timers( self%jedi_run_name ) + if (.not. self%timers_finalised) call final_timing( self%jedi_run_name ) ! Finalise logger call final_logger(self%jedi_run_name) diff --git a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 index c8d0c0f0a..34dd084dc 100644 --- a/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 +++ b/applications/jedi_lfric_tests/source/jedi-interface/jedi_setup_field_meta_data_mod.F90 @@ -108,6 +108,9 @@ subroutine get_field_info(function_space, is_2d, variable_name) case ( "u10m" ) function_space = W3 is_2d = .true. + case ( "land_fraction" ) + function_space = W3 + is_2d = .true. case default write ( log_scratch_space, '(4A)' ) & "jedi_setup_field_meta_data_mod::get_field_info:: ", & diff --git a/applications/jedi_lfric_tests/source/jedi_forecast.f90 b/applications/jedi_lfric_tests/source/jedi_forecast.f90 index e375fc5ec..00150b30d 100644 --- a/applications/jedi_lfric_tests/source/jedi_forecast.f90 +++ b/applications/jedi_lfric_tests/source/jedi_forecast.f90 @@ -19,7 +19,7 @@ ! contact darth@metofice.gov.uk for advice. program jedi_forecast - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use constants_mod, only : PRECISION_REAL, i_def, str_def use field_collection_mod, only : field_collection_type use log_mod, only : log_event, log_scratch_space, & @@ -57,7 +57,7 @@ program jedi_forecast character(*), parameter :: program_name = "jedi_forecast" ! Infrastructure config - call get_initial_filename( filename ) + call parse_command_line( filename ) ! Run object - handles initialization and finalization of required ! infrastructure. Initialize external libraries such as XIOS diff --git a/applications/jedi_lfric_tests/source/jedi_forecast_pseudo.f90 b/applications/jedi_lfric_tests/source/jedi_forecast_pseudo.f90 index 0463708c3..cec71e9d4 100644 --- a/applications/jedi_lfric_tests/source/jedi_forecast_pseudo.f90 +++ b/applications/jedi_lfric_tests/source/jedi_forecast_pseudo.f90 @@ -19,7 +19,7 @@ ! contact darth@metofice.gov.uk for advice. program jedi_forecast_pseudo - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use constants_mod, only : PRECISION_REAL, i_def, str_def use field_collection_mod, only : field_collection_type use log_mod, only : log_event, log_scratch_space, & @@ -56,7 +56,7 @@ program jedi_forecast_pseudo character(*), parameter :: program_name = "jedi_forecast_pseudo" ! Infrastructure configuration - call get_initial_filename( filename ) + call parse_command_line( filename ) ! Run object - handles initialization and finalization of required ! infrastructure. Initialize external libraries such as XIOS diff --git a/applications/jedi_lfric_tests/source/jedi_id_tlm_tests.f90 b/applications/jedi_lfric_tests/source/jedi_id_tlm_tests.f90 index 307801cab..d410965f2 100644 --- a/applications/jedi_lfric_tests/source/jedi_id_tlm_tests.f90 +++ b/applications/jedi_lfric_tests/source/jedi_id_tlm_tests.f90 @@ -46,7 +46,7 @@ ! contact darth@metofice.gov.uk for advice. program jedi_id_tlm_tests - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use constants_mod, only : PRECISION_REAL, i_def, str_def, r_def use field_collection_mod, only : field_collection_type use log_mod, only : log_event, log_scratch_space, & @@ -96,7 +96,7 @@ program jedi_id_tlm_tests character(*), parameter :: program_name = "jedi_id_tlm_tests" ! Infrastructure configuration - call get_initial_filename( filename ) + call parse_command_line( filename ) ! Run object - handles initialization and finalization of required ! infrastructure. Initialize external libraries such as XIOS @@ -194,10 +194,10 @@ program jedi_id_tlm_tests ! Apply the Adjoint dot product test: == ! Evaluate dot product of increments I11 and I21 - dot_product_1 = increment_11%dot_product_with(increment_21) + dot_product_1 = real(increment_11%dot_product_with(increment_21), r_def) ! Evaluate dot product of increments I12 and I22 - dot_product_2 = increment_12%dot_product_with(increment_22) + dot_product_2 = real(increment_12%dot_product_with(increment_22), r_def) ! == ! The two dot products should be nearly identical. The tolerance is diff --git a/applications/jedi_lfric_tests/source/jedi_lfric_tests.f90 b/applications/jedi_lfric_tests/source/jedi_lfric_tests.f90 index 57ad20f79..7bef53fbc 100644 --- a/applications/jedi_lfric_tests/source/jedi_lfric_tests.f90 +++ b/applications/jedi_lfric_tests/source/jedi_lfric_tests.f90 @@ -15,28 +15,34 @@ !> program jedi_lfric_tests - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use driver_collections_mod, only : init_collections, final_collections use driver_comm_mod, only : init_comm, final_comm use driver_config_mod, only : init_config, final_config use driver_log_mod, only : init_logger, final_logger use driver_time_mod, only : init_time, final_time - use driver_timer_mod, only : init_timers, final_timers use gungho_mod, only : gungho_required_namelists use driver_modeldb_mod, only : modeldb_type use lfric_mpi_mod, only : global_mpi use linear_driver_mod, only : initialise, step, finalise use log_mod, only : log_event, & log_level_trace, & - log_scratch_space + log_scratch_space, LOG_LEVEL_WARNING + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path implicit none ! Model run working data set type (modeldb_type) :: modeldb - character(*), parameter :: application_name = "jedi_lfric_tests" - character(:), allocatable :: filename + character(*), parameter :: application_name = "jedi_lfric_tests" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) modeldb%mpi => global_mpi @@ -60,11 +66,14 @@ program jedi_lfric_tests call modeldb%io_contexts%initialise(application_name, 100) call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) + call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) - call init_timers( application_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, application_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) deallocate( filename ) @@ -82,7 +91,7 @@ program jedi_lfric_tests call final_time( modeldb ) call final_collections() - call final_timers( application_name ) + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/jedi_lfric_tests/source/jedi_tlm_forecast_tl.f90 b/applications/jedi_lfric_tests/source/jedi_tlm_forecast_tl.f90 index a5467606a..b3c2aa004 100644 --- a/applications/jedi_lfric_tests/source/jedi_tlm_forecast_tl.f90 +++ b/applications/jedi_lfric_tests/source/jedi_tlm_forecast_tl.f90 @@ -21,7 +21,7 @@ ! contact darth@metofice.gov.uk for advice. program jedi_tlm_forecast_tl - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use constants_mod, only : PRECISION_REAL, i_def, str_def use field_collection_mod, only : field_collection_type use log_mod, only : log_event, log_scratch_space, & @@ -61,15 +61,15 @@ program jedi_tlm_forecast_tl character(*), parameter :: program_name = "jedi_tlm_forecast_tl" + ! Infrastructure config + call parse_command_line( filename ) + call log_event( 'Running ' // program_name // ' ...', LOG_LEVEL_ALWAYS ) write(log_scratch_space,'(A)') & 'Application built with '//trim(PRECISION_REAL)// & '-bit real numbers' call log_event( log_scratch_space, LOG_LEVEL_ALWAYS ) - ! Infrastructure config - call get_initial_filename( filename ) - ! Run object - handles initialization and finalization of required ! infrastructure. Initialize external libraries such as XIOS call jedi_run%initialise( program_name, model_communicator ) diff --git a/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 b/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 index f2266fdb5..2154463fd 100644 --- a/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 +++ b/applications/jedi_lfric_tests/source/jedi_tlm_tests.f90 @@ -34,8 +34,8 @@ program jedi_tlm_tests - use cli_mod, only : get_initial_filename - use constants_mod, only : PRECISION_REAL, i_def, str_def, r_def + use cli_mod, only : parse_command_line + use constants_mod, only : PRECISION_REAL, i_def, str_def, r_def, l_def use field_collection_mod, only : field_collection_type use log_mod, only : log_event, log_scratch_space, & LOG_LEVEL_ALWAYS, LOG_LEVEL_ERROR, & @@ -71,10 +71,12 @@ program jedi_tlm_tests integer( kind=i_def ) :: model_communicator type( jedi_duration_type ) :: forecast_length type( namelist_type ), pointer :: jedi_lfric_settings_config + type( namelist_type ), pointer :: jedi_increment_config + logical( kind=l_def ) :: real_increment character( str_def ) :: forecast_length_str real( kind=r_def ) :: dot_product_1 real( kind=r_def ) :: dot_product_2 - real( kind=r_def ), parameter :: absolute_tolerance = 1.0E-4_r_def + real( kind=r_def ) :: absolute_tolerance real( kind=r_def ) :: machine_tolerance real( kind=r_def ) :: absolute_diff real( kind=r_def ) :: relative_diff @@ -82,7 +84,7 @@ program jedi_tlm_tests character(*), parameter :: program_name = "jedi_tlm_tests" ! Infrastructure config - call get_initial_filename( filename ) + call parse_command_line( filename ) ! Run object - handles initialization and finalization of required ! infrastructure. Initialize external libraries such as XIOS @@ -110,6 +112,12 @@ program jedi_tlm_tests ! Create geometry call geometry%initialise( model_communicator, configuration ) + ! Create inc_initial, either from file or random + call inc_initial%initialise( geometry, configuration ) + jedi_increment_config => configuration%get_namelist('jedi_increment') + call jedi_increment_config%get_value( 'initialise_via_read', real_increment ) + if (.not. real_increment) call inc_initial%random() + ! Create state call state%initialise( geometry, configuration ) @@ -127,10 +135,6 @@ program jedi_tlm_tests ! ---- Perform the adjoint test - ! Create inc_initial and randomise - call inc_initial%initialise( geometry, configuration ) - call inc_initial%random() - ! Check the norm is not zero if (inc_initial%norm() <= 0.0_r_def) then call log_event("inc_initial norm not > 0.0", LOG_LEVEL_ERROR) @@ -148,7 +152,7 @@ program jedi_tlm_tests end if ! Compute - dot_product_1 = inc%scaled_dot_product_with_itself() + dot_product_1 = real(inc%scaled_dot_product_with_itself(), r_def) ! Propagate via AD model call linear_model%forecastAD( inc, forecast_length ) @@ -158,13 +162,14 @@ program jedi_tlm_tests end if ! Compute - dot_product_2 = inc%dot_product_with(inc_initial) + dot_product_2 = real(inc%dot_product_with(inc_initial), r_def) ! The two dot products should be nearly identical. The tolerance is included ! due to differences in order of operations and solver non-convergence. absolute_diff = abs( dot_product_1 - dot_product_2 ) machine_tolerance = spacing( max( abs( dot_product_1 ), abs( dot_product_2 ) ) ) relative_diff = absolute_diff / machine_tolerance + call jedi_lfric_settings_config%get_value( 'adjoint_test_tolerance', absolute_tolerance ) if (absolute_diff > absolute_tolerance ) then call run%finalise_timers() ! We still want timing info even if the test fails write( log_scratch_space, * ) "Adjoint test FAILED", & diff --git a/applications/jules/Makefile b/applications/jules/Makefile index f9b078092..0a8f311c9 100644 --- a/applications/jules/Makefile +++ b/applications/jules/Makefile @@ -124,10 +124,15 @@ build: ALWAYS PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" + $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute_pass.mk \ + SOURCE_DIR=$(WORKING_DIR) \ + OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute.mk \ SOURCE_DIR=$(WORKING_DIR) \ OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" $(call MESSAGE,========================================) diff --git a/applications/jules/build/compile_options.mk b/applications/jules/build/compile_options.mk index bf4bad539..3ab2dcbf3 100644 --- a/applications/jules/build/compile_options.mk +++ b/applications/jules/build/compile_options.mk @@ -13,7 +13,8 @@ $(info UM physics specific compile options) include $(PROJECT_DIR)/build/fortran/$(FORTRAN_COMPILER).mk -science/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) +casim/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) +ukca/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) jules/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) socrates/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) legacy/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) diff --git a/applications/jules/build/psyclone_transmute_file_list.mk b/applications/jules/build/psyclone_transmute_file_list.mk index dc6e63654..61fa12ff2 100644 --- a/applications/jules/build/psyclone_transmute_file_list.mk +++ b/applications/jules/build/psyclone_transmute_file_list.mk @@ -18,6 +18,11 @@ export PSYCLONE_PHYSICS_FILES = ##### TRANSMUTE_INCLUDE_METHOD specify_include ##### +# List to use PSyclone explicitly without any opt script +# This will remove hand written (OMP) directives in the source +# Used by both methods, specify_include and specify_exclude +export PSYCLONE_PASS_NO_SCRIPT = + ##### TRANSMUTE_INCLUDE_METHOD specify_exclude ##### # For GPU, we may want to use more generic local.py transformation scripts and psyclone by directory. # Advise which directories to pass to PSyclone. diff --git a/applications/jules/example/configuration.nml b/applications/jules/example/configuration.nml index fd648227e..5000fe6ad 100644 --- a/applications/jules/example/configuration.nml +++ b/applications/jules/example/configuration.nml @@ -223,6 +223,9 @@ write_minmax_tseries=.false., l_hydrology=.true., l_var_rainfrac=.true., / +&jules_model_environment_lfric +l_jules_parent='lfric', +/ &jules_nvegparm albsnc_nvg_io=0.4,0.8,0.8,0.8, albsnf_nvg_io=0.18,0.12,-1.0,0.75, @@ -300,12 +303,31 @@ rho_snow_fresh=109.0, unload_rate_u=2.31e-6,2.31e-6,0.0,0.0,0.0, / &jules_surface +all_tiles='off', +beta1=0.83, +beta2=0.93, +beta_cnv_bl=0.04, cor_mo_iter='improved', +fd_hill_option='capped_lowhill', fd_stability_dep='none', formdrag='dist_drag', +fwe_c3=0.5, +fwe_c4=20000.0, +hleaf=5.7e4, +hwood=1.1e4, +i_modiscopt='on', +iscrntdiag='decoupled_trans', l_anthrop_heat_src=.false., +l_epot_corr=.true., +l_elev_land_ice=.false., +l_elev_lw_down=.false., +l_flake_model=.false., +l_land_ice_imp=.true., +l_mo_buoyancy_calc=.true., +l_point_data=.false., l_urban2t=.false., l_vary_z0m_soil=.true., +orog_drag_param=0.15, srf_ex_cnv_gust=.true., / &jules_surface_types @@ -453,6 +475,7 @@ tau_u=0.55, &transport adjust_theta=.true., adjust_theta_above=30000.0, +adjust_tracer_equation=.false. adjust_vhv_wind=.true., ageofair_reset_level=10, broken_w2_projection=.false., diff --git a/applications/jules/example/iodef.xml b/applications/jules/example/iodef.xml index 2c047aa1d..b649bf0f4 100644 --- a/applications/jules/example/iodef.xml +++ b/applications/jules/example/iodef.xml @@ -101,7 +101,7 @@ performance - 1.0 + 1.0 diff --git a/applications/jules/optimisation/uoe-dial3 b/applications/jules/optimisation/uoe-dial3 new file mode 120000 index 000000000..e5b7210c6 --- /dev/null +++ b/applications/jules/optimisation/uoe-dial3 @@ -0,0 +1 @@ +meto-ex1a \ No newline at end of file diff --git a/applications/jules/optimisation/uoe-dial3/psykal/global.py b/applications/jules/optimisation/uoe-dial3/psykal/global.py deleted file mode 100644 index 952b2d506..000000000 --- a/applications/jules/optimisation/uoe-dial3/psykal/global.py +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################## -# Copyright (c) 2025, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## - - -''' -PSyclone transformation script for the LFRic (Dynamo0p3) API to apply -colouring, OpenMP and redundant computation to the level-1 halo for -the initialisation built-ins generically. - -''' - -from psyclone_tools import (redundant_computation_setval, colour_loops, - openmp_parallelise_loops, - view_transformed_schedule) - - -def trans(psyir): - ''' - Applies PSyclone colouring, OpenMP and redundant computation - transformations. - - :param psyir: the PSyIR of the PSy-layer. - :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` - - ''' - redundant_computation_setval(psyir) - colour_loops(psyir) - openmp_parallelise_loops(psyir) - view_transformed_schedule(psyir) diff --git a/applications/jules/optimisation/uoe-epic b/applications/jules/optimisation/uoe-epic new file mode 120000 index 000000000..e5b7210c6 --- /dev/null +++ b/applications/jules/optimisation/uoe-epic @@ -0,0 +1 @@ +meto-ex1a \ No newline at end of file diff --git a/applications/jules/optimisation/uoe-epic/psykal/global.py b/applications/jules/optimisation/uoe-epic/psykal/global.py deleted file mode 100644 index 952b2d506..000000000 --- a/applications/jules/optimisation/uoe-epic/psykal/global.py +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################## -# Copyright (c) 2025, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## - - -''' -PSyclone transformation script for the LFRic (Dynamo0p3) API to apply -colouring, OpenMP and redundant computation to the level-1 halo for -the initialisation built-ins generically. - -''' - -from psyclone_tools import (redundant_computation_setval, colour_loops, - openmp_parallelise_loops, - view_transformed_schedule) - - -def trans(psyir): - ''' - Applies PSyclone colouring, OpenMP and redundant computation - transformations. - - :param psyir: the PSyIR of the PSy-layer. - :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` - - ''' - redundant_computation_setval(psyir) - colour_loops(psyir) - openmp_parallelise_loops(psyir) - view_transformed_schedule(psyir) diff --git a/applications/jules/rose-meta/lfric-jules/version30_31.py b/applications/jules/rose-meta/lfric-jules/version30_31.py new file mode 100644 index 000000000..4a05bb502 --- /dev/null +++ b/applications/jules/rose-meta/lfric-jules/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-jules + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/jules/rose-meta/lfric-jules/versions.py b/applications/jules/rose-meta/lfric-jules/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/jules/rose-meta/lfric-jules/versions.py +++ b/applications/jules/rose-meta/lfric-jules/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/jules/rose-meta/lfric-jules/vn3.1/rose-meta.conf b/applications/jules/rose-meta/lfric-jules/vn3.1/rose-meta.conf new file mode 100644 index 000000000..47acbb91f --- /dev/null +++ b/applications/jules/rose-meta/lfric-jules/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-gungho/vn3.1 diff --git a/applications/jules/source/jules.f90 b/applications/jules/source/jules.f90 index 5f824fa7c..457e85cc3 100644 --- a/applications/jules/source/jules.f90 +++ b/applications/jules/source/jules.f90 @@ -16,27 +16,32 @@ program jules - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use driver_collections_mod, only: init_collections, final_collections use driver_comm_mod, only: init_comm, final_comm use driver_config_mod, only: init_config, final_config use driver_counter_mod, only: init_counters, final_counters use driver_log_mod, only: init_logger, final_logger use driver_time_mod, only: init_time, final_time - use driver_timer_mod, only: init_timers, final_timers use gungho_mod, only: gungho_required_namelists use driver_modeldb_mod, only: modeldb_type use gungho_driver_mod, only: initialise, step, finalise use lfric_mpi_mod, only: global_mpi + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path implicit none ! Model run working data set type(modeldb_type) :: modeldb - character(*), parameter :: application_name = "jules" + character(*), parameter :: application_name = "jules" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers - character(:), allocatable :: filename + call parse_command_line( filename ) modeldb%mpi => global_mpi @@ -63,11 +68,13 @@ program jules call modeldb%io_contexts%initialise(application_name, 100) call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) - call init_timers( application_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, application_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) call init_counters( application_name ) @@ -84,7 +91,7 @@ program jules call final_counters( application_name ) call final_time( modeldb ) call final_collections() - call final_timers( application_name ) + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/lfric2lfric/example/configuration.nml b/applications/lfric2lfric/example/configuration.nml index b70cd2d22..ea19ff585 100644 --- a/applications/lfric2lfric/example/configuration.nml +++ b/applications/lfric2lfric/example/configuration.nml @@ -5,6 +5,7 @@ destination_geometry = 'spherical', destination_mesh_name = 'dynamics', destination_meshfile_prefix = 'mesh_C24_MG', destination_topology = 'fully_periodic', +mode = 'ics', origin_domain = 'global', prepartitioned_meshes = .false., regrid_method = 'oasis', diff --git a/applications/lfric2lfric/example/iodef.xml b/applications/lfric2lfric/example/iodef.xml index 89d0b536b..42fddc6f0 100644 --- a/applications/lfric2lfric/example/iodef.xml +++ b/applications/lfric2lfric/example/iodef.xml @@ -82,7 +82,7 @@ performance - 1.0 + 1.0 diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf index 9b114f748..dbe84fe41 100644 --- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf +++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/HEAD/rose-meta.conf @@ -32,6 +32,7 @@ fail-if=this == namelist:lfric2lfric=source_mesh_name ; help=Mesh topologies are held in UGRID conformant NetCDF files which =may contain more than one mesh topology. This tag-name identifies =the mesh topology to use from the mesh file namelist:lfric2lfric=destination_meshfile_prefix. +ns=namelist/lfric2lfric/configuration !string_length=default type=character @@ -41,6 +42,7 @@ description=Location of destination 2D mesh input file(s) (prefix). help=Input files for 2D meshes are in NetCDF file format. The mesh topologies in the file should =be conformant to UGRID convention. = +ns=namelist/lfric2lfric/configuration !string_length=filename type=character @@ -78,6 +80,20 @@ ns=namelist/lfric2lfric/configuration !string_length=filename type=character +[namelist:lfric2lfric=mode] +compulsory=true +description=Generate Initial Conditions (ics) or Lateral Boundary Conditions (lbc) +!enumeration=true +help=Indicates whether to generate data on the destination mesh from data + =on the source mesh (ics), or whether to generate lateral boundary + =conditions for a regional destination mesh from data on the source + =mesh (lbc). +ns=namelist/lfric2lfric/configuration +trigger=namelist:lfric2lfric=source_file_lbc: 'lbc' ; + =namelist:lfric2lfric=weight_file_lbc: 'lbc' ; +value-titles=Initial conditions,Boundary conditions +values='ics','lbc' + [namelist:lfric2lfric=origin_domain] compulsory=true description=The domain that will be the source of the values to be regridded. @@ -85,6 +101,7 @@ description=The domain that will be the source of the values to be regridded. help=The LAM domain can only be used as an origin domain when regridding =to another LAM mesh, lfric2lfric does not support LAM-to-global or =LAM-to-LBC regridding. +ns=namelist/lfric2lfric/configuration sort-key=1 value-titles=global, LAM values='global', 'LAM' @@ -106,6 +123,7 @@ help=Input mesh files may contain global meshes whose extents are intended to co =Note: With increasing mesh size, at some point prepartitioned meshes may become = necessary. = +ns=namelist/lfric2lfric/configuration trigger=namelist:partitioning: .false. ; type=logical @@ -132,13 +150,24 @@ help=Method used to regrid between the source and destination mesh, = 'Oasis' : The regridding between the source and destination = grids is make through the weigh files generated = by an external tool, applied by the OASIS - = library. + = library. The weight file is specified in the + = OASIS namcouple file = ns=namelist/lfric2lfric/configuration trigger=namelist:lfric2lfric=weight_file: 'lfric2lfric' ; + =namelist:lfric2lfric=weight_file_lbc: 'lfric2lfric' ; value-titles=Inter-grid maps, LFRic2LFRic, Oasis values='map','lfric2lfric','oasis' +[namelist:lfric2lfric=source_file_lbc] +compulsory=true +description=Location of the lbc source file +help=File from where lateral boundary conditions will be generated + = +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + [namelist:lfric2lfric=source_geometry] compulsory=true description=The geometry on which the source domain is embedded @@ -158,6 +187,7 @@ fail-if=this == namelist:lfric2lfric=destination_mesh_name ; help=Mesh topologies are held in UGRID conformant NetCDF files which =may contain more than one mesh topology. This tag-name identifies =the mesh topology to use from the mesh file namelist:lfric2lfric=source_meshfile_prefix. +ns=namelist/lfric2lfric/configuration !string_length=default type=character @@ -168,6 +198,7 @@ fail-if=namelist:lfric2lfric=regrid_method == "'map'" and this != namelist:lfric help=Input files for 2D meshes are in NetCDF file format. The mesh topologies in the file should =be conformant to UGRID convention. = +ns=namelist/lfric2lfric/configuration !string_length=filename type=character @@ -218,16 +249,29 @@ help=Target domains currently not supported include: = LAM => LBC = LAM => global = +ns=namelist/lfric2lfric/configuration sort-key=2 value-titles=global, LAM, LBC values='global', 'LAM', 'LBC' [namelist:lfric2lfric=weight_file] compulsory=true -description=Weight file for mesh regridding +description=Weight file for ics mesh regridding +fail-if=this == '' ; +help=Location of the weight file used to interpolate + =between the source and destination meshes + =when creating checkpoint files +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=weight_file_lbc] +compulsory=true +description=Weight file for lbc mesh regridding fail-if=this == '' ; help=Location of the weight file used to interpolate =between the source and destination meshes + =when creating lateral boundary files ns=namelist/lfric2lfric/configuration !string_length=filename type=character diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/version30_31.py b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/version30_31.py new file mode 100644 index 000000000..b53f1e61c --- /dev/null +++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/version30_31.py @@ -0,0 +1,229 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t48(MacroUpgrade): + """Upgrade macro for ticket #48 by Juan M Castillo.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t48" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric2lfric + self.add_setting(config, ["namelist:lfric2lfric", "mode"], "'ics'") + self.add_setting( + config, + ["namelist:lfric2lfric", "source_file_lbc"], + "'source_file_lbc'", + ) + self.add_setting( + config, + ["namelist:lfric2lfric", "weight_file_lbc"], + "'weight_file_lbc'", + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t48" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-lfric2lfric + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py +++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/vn3.1/rose-meta.conf b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/vn3.1/rose-meta.conf new file mode 100644 index 000000000..30b4384d5 --- /dev/null +++ b/applications/lfric2lfric/rose-meta/lfric-lfric2lfric/vn3.1/rose-meta.conf @@ -0,0 +1,292 @@ +import=lfric-gungho/vn3.1 + +[namelist:base_mesh] +compulsory=false + +[namelist:base_mesh=prepartitioned] +compulsory=false +!!trigger=namelist:partitioning: .false.; + +[namelist:lfric2lfric] +compulsory=true +description= +ns=namelist/lfri2lfric +title=lfric2lfric + +[namelist:lfric2lfric=destination_geometry] +compulsory=true +description=The geometry on which the destination domain is embedded +!enumeration=true +fail-if=this == "'planar'" and namelist:lfric2lfric=destination_topology != "'non_periodic'"; +help=Along with topology this describes the domain. The geometry is the shape + =on which the domain is embedded. This is currently either 'spherical' or + ='planar'. +ns=namelist/lfric2lfric/configuration +value-titles=Planar, Spherical +values='planar', 'spherical' + +[namelist:lfric2lfric=destination_mesh_name] +compulsory=true +description=Tag-name for destination-mesh +fail-if=this == namelist:lfric2lfric=source_mesh_name ; +help=Mesh topologies are held in UGRID conformant NetCDF files which + =may contain more than one mesh topology. This tag-name identifies + =the mesh topology to use from the mesh file namelist:lfric2lfric=destination_meshfile_prefix. +ns=namelist/lfric2lfric/configuration +!string_length=default +type=character + +[namelist:lfric2lfric=destination_meshfile_prefix] +compulsory=true +description=Location of destination 2D mesh input file(s) (prefix). +help=Input files for 2D meshes are in NetCDF file format. The mesh topologies in the file should + =be conformant to UGRID convention. + = +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=destination_topology] +compulsory=true +description=Describes the periodicity of the destination domain. +!enumeration=true +fail-if=this != "'fully_periodic'" and namelist:partitioning=partitioner == "'cubedsphere'" ; +help=Together with the geometry this describes the domain. The topology is the + =periodicity of the base mesh. A mesh over the whole globe would have + =spherical geometry and fully_periodic topology, while a regional model + =on the sphere would have spherical geometry and non_periodic topology. + =Note that to run a regional model in limited-area mode with lateral boundary + =conditions, namelist:boundaries=limited_area also needs to be set to "true". +ns=namelist/lfric2lfric/configuration +value-titles=Fully-periodic, Non-periodic +values='fully_periodic', 'non_periodic' + +[namelist:lfric2lfric=dst_ancil_directory] +compulsory=true +description=Directory for destination ancillary files +help=Path to the directory where LFRic ancillaries for the destination + =mesh are stored +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=dst_orography_mean_ancil_path] +compulsory=true +description=Path to mean destination orography file from the destination + =ancillary files directory +help=This file contains global surface altitude information used for + =the destination orography +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=mode] +compulsory=true +description=Generate Initial Conditions (ics) or Lateral Boundary Conditions (lbc) +!enumeration=true +help=Indicates whether to generate data on the destination mesh from data + =on the source mesh (ics), or whether to generate lateral boundary + =conditions for a regional destination mesh from data on the source + =mesh (lbc). +ns=namelist/lfric2lfric/configuration +trigger=namelist:lfric2lfric=source_file_lbc: 'lbc' ; + =namelist:lfric2lfric=weight_file_lbc: 'lbc' ; +value-titles=Initial conditions,Boundary conditions +values='ics','lbc' + +[namelist:lfric2lfric=origin_domain] +compulsory=true +description=The domain that will be the source of the values to be regridded. +!enumeration=true +help=The LAM domain can only be used as an origin domain when regridding + =to another LAM mesh, lfric2lfric does not support LAM-to-global or + =LAM-to-LBC regridding. +ns=namelist/lfric2lfric/configuration +sort-key=1 +value-titles=global, LAM +values='global', 'LAM' + +[namelist:lfric2lfric=prepartitioned_meshes] +compulsory=true +description=Load pre-partitioned source and destination meshes +help=Input mesh files may contain global meshes whose extents are intended to cover + =the entire model domain. These may require partitioning in to a number of local + =meshes (1 per processor rank) at runtime depending on the number of ranks + =requested to perform the regridding between the source and destination meshes. + = + =If prepartitioned meshes are not used the model will expect global meshes + =in the mesh input file to be partitioned at runtime. + = + =For simplicity, pre-partitioning can not be selected individually for the + =source and destination meshes. + = + =Note: With increasing mesh size, at some point prepartitioned meshes may become + = necessary. + = +ns=namelist/lfric2lfric/configuration +trigger=namelist:partitioning: .false. ; +type=logical + +[namelist:lfric2lfric=regrid_method] +compulsory=true +description=Regridding method +!enumeration=true +help=Method used to regrid between the source and destination mesh, + =there are three options available: + = + = 'Inter-grid maps' : Use inter-grids maps which link suitable pairs + = of input meshes. Inter-grid maps are restricted + = to mesh pairs where cells on one mesh are a + = gridded sub-division of cells from the other mesh. + = These inter-grid maps are included in the mesh + = files, if requested from the mesh generators when + = configured to output multiple meshes. + = + = 'LFRic2LFRic' : The regridding between the source and destination + = grids is made through the weight files generated + = by an external tool, applied by a lfric2lfric + = kernel. + = + = 'Oasis' : The regridding between the source and destination + = grids is make through the weigh files generated + = by an external tool, applied by the OASIS + = library. The weight file is specified in the + = OASIS namcouple file + = +ns=namelist/lfric2lfric/configuration +trigger=namelist:lfric2lfric=weight_file: 'lfric2lfric' ; + =namelist:lfric2lfric=weight_file_lbc: 'lfric2lfric' ; +value-titles=Inter-grid maps, LFRic2LFRic, Oasis +values='map','lfric2lfric','oasis' + +[namelist:lfric2lfric=source_file_lbc] +compulsory=true +description=Location of the lbc source file +help=File from where lateral boundary conditions will be generated + = +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=source_geometry] +compulsory=true +description=The geometry on which the source domain is embedded +!enumeration=true +fail-if=this == "'planar'" and namelist:lfric2lfric=source_topology != "'non_periodic'"; +help=Along with topology this describes the domain. The geometry is the shape + =on which the domain is embedded. This is currently either 'spherical' or + ='planar'. +ns=namelist/lfric2lfric/configuration +value-titles=Planar, Spherical +values='planar', 'spherical' + +[namelist:lfric2lfric=source_mesh_name] +compulsory=true +description=Tag-name for source-mesh +fail-if=this == namelist:lfric2lfric=destination_mesh_name ; +help=Mesh topologies are held in UGRID conformant NetCDF files which + =may contain more than one mesh topology. This tag-name identifies + =the mesh topology to use from the mesh file namelist:lfric2lfric=source_meshfile_prefix. +ns=namelist/lfric2lfric/configuration +!string_length=default +type=character + +[namelist:lfric2lfric=source_meshfile_prefix] +compulsory=true +description=Location of source 2D mesh input file(s) (prefix). +fail-if=namelist:lfric2lfric=regrid_method == "'map'" and this != namelist:lfric2lfric=destination_meshfile_prefix ; +help=Input files for 2D meshes are in NetCDF file format. The mesh topologies in the file should + =be conformant to UGRID convention. + = +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=source_topology] +compulsory=true +description=Describes the periodicity of the source domain. +!enumeration=true +fail-if=this != "'fully_periodic'" and namelist:partitioning=partitioner == "'cubedsphere'" ; +help=Together with the geometry this describes the domain. The topology is the + =periodicity of the base mesh. A mesh over the whole globe would have + =spherical geometry and fully_periodic topology, while a regional model + =on the sphere would have spherical geometry and non_periodic topology. + =Note that to run a regional model in limited-area mode with lateral boundary + =conditions, namelist:boundaries=limited_area also needs to be set to "true". +ns=namelist/lfric2lfric/configuration +value-titles=Fully-periodic, Non-periodic +values='fully_periodic', 'non_periodic' + +[namelist:lfric2lfric=src_ancil_directory] +compulsory=true +description=Directory for source ancillary files +help=Path to the directory where LFRic ancillaries for the source + =mesh are stored +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=src_orography_mean_ancil_path] +compulsory=true +description=Path to mean source orography file from the source + =ancillary files directory +help=This file contains global surface altitude information used for + =the source orography +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=target_domain] +compulsory=true +description=The domain type that the source data will be regridded to. +!enumeration=true +fail-if=this == "'LBC'" and namelist:lfric2lfric=origin_domain == "'LAM'" # LAM cannot provide source values for LBC creation + =this == "'global'" and namelist:lfric2lfric=origin_domain == "'LAM'" # LAM cannot currently be regrid into global +help=Target domains currently not supported include: + = + = origin => target + = ---------------- + = LAM => LBC + = LAM => global + = +ns=namelist/lfric2lfric/configuration +sort-key=2 +value-titles=global, LAM, LBC +values='global', 'LAM', 'LBC' + +[namelist:lfric2lfric=weight_file] +compulsory=true +description=Weight file for ics mesh regridding +fail-if=this == '' ; +help=Location of the weight file used to interpolate + =between the source and destination meshes + =when creating checkpoint files +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:lfric2lfric=weight_file_lbc] +compulsory=true +description=Weight file for lbc mesh regridding +fail-if=this == '' ; +help=Location of the weight file used to interpolate + =between the source and destination meshes + =when creating lateral boundary files +ns=namelist/lfric2lfric/configuration +!string_length=filename +type=character + +[namelist:partitioning] +duplicate=true +!instance_key_member=mesh_type + +[namelist:partitioning=mesh_type] +compulsory=true +description=The purpose of the mesh +!enumeration=true +help=The mesh can be used to perform a LFRic forecast (Dynamics), + =or to describe the source and the destination grids in + =the lfric2lfric regridding program. +ns=namelist/lfric2lfric/configuration +value-titles=Dynamics, Source, Destination +values='dynamics', 'source', 'destination' diff --git a/applications/lfric2lfric/source/algorithm/lfric2lfric_oasis_regrid_mod.X90 b/applications/lfric2lfric/source/algorithm/lfric2lfric_oasis_regrid_mod.X90 index 12fcaf4d6..18e87d041 100644 --- a/applications/lfric2lfric/source/algorithm/lfric2lfric_oasis_regrid_mod.X90 +++ b/applications/lfric2lfric/source/algorithm/lfric2lfric_oasis_regrid_mod.X90 @@ -32,6 +32,7 @@ module lfric2lfric_oasis_regrid_mod use constants_mod, only: i_def, r_def, l_def use fs_continuity_mod, only: W3, Wtheta use driver_modeldb_mod, only: modeldb_type + use model_clock_mod, only: model_clock_type #ifdef MCT use coupling_mod, only: coupling_type, & get_coupling_from_collection @@ -60,16 +61,18 @@ contains !> @brief Perform regridding of a field collection using weight files !> and OASIS !> @param[inout] modeldb The structure that holds model state + !> @param[inout] clock Clock for oasis time !> @param[out] field_dst Field in the destination mesh obtained !> after regridding the field in the !> source mesh !> @param[in] field_src Field in the source mesh - subroutine lfric2lfric_oasis_regrid(modeldb, field_dst, field_src) + subroutine lfric2lfric_oasis_regrid(modeldb, clock, field_dst, field_src) implicit none type(modeldb_type), intent(inout) :: modeldb + type(model_clock_type), intent(inout) :: clock type(field_type), pointer, intent(inout) :: field_dst type(field_type), pointer, intent(in) :: field_src @@ -124,7 +127,7 @@ contains coupling_ptr => get_coupling_from_collection(modeldb%values, "coupling" ) local_index => coupling_ptr%get_local_index() call coupler_exchange_2d%initialise(src_field, local_index) - call coupler_exchange_2d%set_time(modeldb%clock) + call coupler_exchange_2d%set_time(clock) call coupler_exchange_2d%copy_from_lfric(ierror) call coupler_exchange_2d%clear() @@ -133,7 +136,7 @@ contains coupling_ptr => get_coupling_from_collection(modeldb%values, "coupling_dst" ) local_index => coupling_ptr%get_local_index() call coupler_exchange_2d%initialise(dst_field, local_index) - call coupler_exchange_2d%set_time(modeldb%clock) + call coupler_exchange_2d%set_time(clock) call coupler_exchange_2d%copy_to_lfric(ierror) call coupler_exchange_2d%clear() @@ -143,7 +146,7 @@ contains dst_field, l, k)) ! Update the coupling time - is_running = modeldb%clock%tick() + is_running = clock%tick() end do end do diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 index c38f37b34..e02dd5580 100644 --- a/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 +++ b/applications/lfric2lfric/source/driver/lfric2lfric_driver_mod.F90 @@ -7,40 +7,35 @@ !> module lfric2lfric_driver_mod - use constants_mod, only: str_def, i_def, l_def, r_second - use driver_fem_mod, only: final_fem - use driver_io_mod, only: final_io - use driver_modeldb_mod, only: modeldb_type - use field_collection_iterator_mod, only: & - field_collection_iterator_type - use field_collection_mod, only: field_collection_type - use field_mod, only: field_type - use field_parent_mod, only: field_parent_type - use function_space_mod, only: function_space_type - use lfric_xios_context_mod, only: lfric_xios_context_type - use lfric_xios_read_mod, only: read_checkpoint - use lfric_xios_write_mod, only: write_checkpoint - use log_mod, only: log_event, & - log_level_info, & - log_scratch_space - use mesh_collection_mod, only: mesh_collection - use mesh_mod, only: mesh_type - use namelist_mod, only: namelist_type - use sci_checksum_alg_mod, only: checksum_alg + use constants_mod, only: str_def, i_def, l_def, r_second + use driver_fem_mod, only: final_fem + use driver_io_mod, only: final_io + use driver_modeldb_mod, only: modeldb_type + use field_collection_mod, only: field_collection_type + use lfric_xios_action_mod, only: advance + use lfric_xios_context_mod, only: lfric_xios_context_type + use lfric_xios_read_mod, only: read_checkpoint, & + read_state + use lfric_xios_write_mod, only: write_checkpoint, & + write_state + use log_mod, only: log_scratch_space, & + log_event, & + log_level_info + use model_clock_mod, only: model_clock_type + use namelist_mod, only: namelist_type + use sci_checksum_alg_mod, only: checksum_alg + use xios, only: xios_date, xios_get_current_date, & + xios_date_convert_to_string !------------------------------------ ! lfric2lfric modules !------------------------------------ - use lfric2lfric_config_mod, only: regrid_method_map, & - regrid_method_lfric2lfric, & - regrid_method_oasis + use lfric2lfric_config_mod, only: mode_ics, mode_lbc use lfric2lfric_infrastructure_mod, only: initialise_infrastructure, & context_dst, context_src, & source_collection_name, & target_collection_name - use lfric2lfric_map_regrid_mod, only: lfric2lfric_map_regrid - use lfric2lfric_no_regrid_mod, only: lfric2lfric_no_regrid - use lfric2lfric_oasis_regrid_mod, only: lfric2lfric_oasis_regrid + use lfric2lfric_regrid_mod, only: lfric2lfric_regrid implicit none @@ -56,13 +51,16 @@ module lfric2lfric_driver_mod !! extrusions, XIOS contexts and files, field collections !! and fields. !> @param [in,out] modeldb The structure holding model state - subroutine initialise( modeldb ) + !> @param [in,out] oasis_clock Clock for OASIS exchanges + subroutine initialise( modeldb, oasis_clock ) implicit none - type(modeldb_type), intent(inout) :: modeldb + type(modeldb_type), intent(inout) :: modeldb + type(model_clock_type), allocatable, & + intent(inout) :: oasis_clock - call initialise_infrastructure( modeldb ) + call initialise_infrastructure( modeldb, oasis_clock ) end subroutine initialise @@ -71,24 +69,16 @@ end subroutine initialise !> @details Populates fields in the source field collection with data !! read from the source XIOS context file, regrids the field !! collection to a destination mesh, switches to the destination - !! XIOS context and writes to a checkpoint file. - !! TODO: #262 Porting algorithms and kernels - !! Over one time step, all regridding is performed by algorithm - !! modules specific to the regrid method defined in the - !! configuration. - !! Fields to be regridded are extracted from the source field - !! collection and located in the source dump file using - !! `read_checkpoint`. Corresponding source and target field pairs - !! are passed to the regridding algorithm, written to fields - !! in the destination field collection and then written to - !! an outfile. - !> @param [in,out] modeldb The structure that holds model - !! state - subroutine run( modeldb ) + !! XIOS context and writes to an output file. + !> @param [in,out] modeldb The structure that holds model state + !> @param [in,out] oasis_clock Clock for OASIS exchanges + subroutine run( modeldb, oasis_clock ) implicit none - type(modeldb_type), intent(inout) :: modeldb + type(modeldb_type), intent(inout) :: modeldb + type(model_clock_type), allocatable, & + intent(inout) :: oasis_clock ! LFRic-XIOS constants integer(kind=i_def), parameter :: start_timestep = 1_i_def @@ -96,27 +86,24 @@ subroutine run( modeldb ) ! Namelist variables character(len=str_def) :: start_dump_filename character(len=str_def) :: checkpoint_stem_name + integer(kind=i_def) :: mode integer(kind=i_def) :: regrid_method ! Local parameters type(namelist_type), pointer :: files_nml type(namelist_type), pointer :: lfric2lfric_nml - type(field_collection_type), pointer :: source_fields - type(field_collection_type), pointer :: target_fields - - type(field_collection_iterator_type) :: iter + integer(kind=i_def) :: step, time_steps + logical(kind=l_def) :: is_running + type(xios_date) :: current_date + character(len=32) :: current_date_str + real(kind=r_second) :: checkpoint_times(1) - class(field_parent_type), pointer :: field => null() - type(field_type), pointer :: field_src => null() - type(field_type), pointer :: field_dst => null() + type(field_collection_type), pointer :: source_fields + type(field_collection_type), pointer :: target_fields type(lfric_xios_context_type), pointer :: io_context - character(len=str_def) :: field_name - - real(r_second) :: checkpoint_times(1) - ! Namelist pointers files_nml => modeldb%configuration%get_namelist('files') lfric2lfric_nml => modeldb%configuration%get_namelist('lfric2lfric') @@ -124,61 +111,59 @@ subroutine run( modeldb ) ! Extract configuration variables call files_nml%get_value( 'start_dump_filename', start_dump_filename ) call files_nml%get_value( 'checkpoint_stem_name', checkpoint_stem_name ) + call lfric2lfric_nml%get_value( 'mode', mode ) call lfric2lfric_nml%get_value( 'regrid_method', regrid_method ) ! Point to source and target field collections source_fields => modeldb%fields%get_field_collection(source_collection_name) target_fields => modeldb%fields%get_field_collection(target_collection_name) - call read_checkpoint(source_fields, & - start_timestep, & - start_dump_filename ) - - ! Main loop over fields to be processed - call iter%initialise(source_fields) - do - ! Locate the field to be processed in the field collections - if ( .not.iter%has_next() ) exit - field => iter%next() - field_name = field%get_name() - - call source_fields%get_field(field_name, field_src) - call target_fields%get_field(field_name, field_dst) - - write(log_scratch_space, '(A,A)') "Processing lfric field ", & - trim(field_name) - call log_event(log_scratch_space, log_level_info) - - ! Regrid source field depending on regrid method - select case (regrid_method) - case (regrid_method_map) - call lfric2lfric_map_regrid(field_dst, field_src) - - case (regrid_method_lfric2lfric) - write(log_scratch_space, '(A)') & - 'Regrid method lfric2lfric not implemented yet' - call log_event(log_scratch_space, log_level_info) - - call lfric2lfric_no_regrid(field_dst) - - case (regrid_method_oasis) -#ifdef MCT - call lfric2lfric_oasis_regrid(modeldb, & - field_dst, field_src) -#endif - end select - - ! Free memory of the processed field - call field_src%field_final() - end do - - ! Write output - call modeldb%io_contexts%get_io_context(context_dst, io_context) - call io_context%set_current() - - checkpoint_times(1) = modeldb%clock%seconds_from_steps(modeldb%clock%get_step()) - call write_checkpoint( target_fields, modeldb%values, modeldb%clock, & - checkpoint_stem_name, checkpoint_times ) + ! Read fields and perform the regridding + if (mode == mode_ics) then + call read_checkpoint(source_fields, & + start_timestep, & + start_dump_filename ) + + call lfric2lfric_regrid(modeldb, oasis_clock, source_fields, & + target_fields, regrid_method) + + ! Write output + call modeldb%io_contexts%get_io_context(context_dst, io_context) + call io_context%set_current() + + checkpoint_times(1) = modeldb%clock%seconds_from_steps(modeldb%clock%get_step()) + call write_checkpoint(target_fields, modeldb%values, modeldb%clock, & + checkpoint_stem_name, checkpoint_times) + + else if (mode == mode_lbc) then + time_steps = modeldb%clock%get_last_step() - & + modeldb%clock%get_first_step() + 1 + + do step=1, time_steps + call xios_get_current_date(current_date) + call xios_date_convert_to_string(current_date, current_date_str) + write(log_scratch_space, '(A)') 'Regridding at xios date: ' // & + current_date_str + call log_event( log_scratch_space, log_level_info ) + + call read_state(source_fields) + + call lfric2lfric_regrid(modeldb, oasis_clock, source_fields, & + target_fields, regrid_method) + + is_running = modeldb%clock%tick() + + call modeldb%io_contexts%get_io_context(context_dst, io_context) + call io_context%set_current() + call advance(io_context, modeldb%clock) + + call write_state(target_fields, prefix='lbc_') + + call modeldb%io_contexts%get_io_context(context_src, io_context) + call io_context%set_current() + call advance(io_context, modeldb%clock) + end do + end if ! Write checksum call checksum_alg("lfric2lfric", field_collection=target_fields) diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 index 0258c78d9..ab2a73b09 100644 --- a/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 +++ b/applications/lfric2lfric/source/driver/lfric2lfric_init_mod.f90 @@ -11,15 +11,18 @@ module lfric2lfric_init_mod - use constants_mod, only : i_def, r_def, str_def - use driver_modeldb_mod, only : modeldb_type - use field_collection_mod, only : field_collection_type - use log_mod, only : log_event, & - log_level_info - use mesh_mod, only : mesh_type + use constants_mod, only: i_def, r_def, str_def + use driver_modeldb_mod, only: modeldb_type + use field_collection_mod, only: field_collection_type + use lfric_xios_context_mod, only: lfric_xios_context_type + use log_mod, only: log_event, & + log_level_info + use mesh_mod, only: mesh_type + use netcdf, only: nf90_max_name ! lfric2lfric mods - use lfric2lfric_field_init_mod, only : get_field_list, field_maker + use lfric2lfric_config_mod, only: mode_ics, mode_lbc + use lfric2lfric_field_init_mod, only: get_field_list, field_maker implicit none private @@ -31,23 +34,32 @@ module lfric2lfric_init_mod !> @details Calls out to field_maker to initialise fields on given field !! collection. !> @param [in,out] modeldb Holds model state + !> @param [in] context_src The name of the XIOS context that + !! will hold the source file + !> @param [in] context_dst The name of the XIOS context that + !! will hold the file to be written !> @param [in] start_dump_filename File to get field names from + !> @param [in] mode Process ics or lbcs !> @param [in] origin_collection_name Holds the origin fields !> @param [in] origin_mesh Mesh to initialise 3D fields !> @param [in] origin_twod_mesh Mesh to initialise 2D fields !> @param [in] target_collection_name Holds target fields !> @param [in] target_mesh Mesh for target 3D fields !> @param [in] target_twod_mesh Mesh for target 2D fields - subroutine init_lfric2lfric( modeldb, start_dump_filename, & - origin_collection_name, & - origin_mesh, origin_twod_mesh, & - target_collection_name, & + subroutine init_lfric2lfric( modeldb, context_src, context_dst, & + start_dump_filename, mode, & + origin_collection_name, & + origin_mesh, origin_twod_mesh, & + target_collection_name, & target_mesh, target_twod_mesh ) implicit none type(modeldb_type), intent(inout) :: modeldb + character(len=*), intent(in) :: context_src + character(len=*), intent(in) :: context_dst character(len=*), intent(in) :: start_dump_filename + integer(i_def), intent(in) :: mode character(len=*), intent(in) :: origin_collection_name type(mesh_type), intent(in), pointer :: origin_mesh type(mesh_type), intent(in), pointer :: origin_twod_mesh @@ -62,14 +74,24 @@ subroutine init_lfric2lfric( modeldb, start_dump_filename, & ! For get_field_list returns integer(kind=i_def) :: num_fields character(len=str_def), allocatable :: config_list(:) + character(len=nf90_max_name) :: prefix + + ! Source context pointer and temporary context for setup + type(lfric_xios_context_type), pointer :: io_context ! Looping variable integer(kind=i_def) :: i call log_event( 'lfric2lfric: Initialising miniapp ...', log_level_info ) + if (mode == mode_ics) then + prefix = 'restart_' + else if (mode == mode_lbc) then + prefix = '' + end if + ! Get field names from filename and validate presence in iodef.xml - call get_field_list( num_fields, config_list, start_dump_filename ) + call get_field_list( num_fields, config_list, start_dump_filename, prefix ) !-------------------------------------------------------------------------- ! Initialise Source Fields @@ -83,7 +105,8 @@ subroutine init_lfric2lfric( modeldb, start_dump_filename, & call field_maker( field_collection, & config_list(i), & origin_mesh, & - origin_twod_mesh ) + origin_twod_mesh, & + prefix ) end do !-------------------------------------------------------------------------- @@ -93,13 +116,26 @@ subroutine init_lfric2lfric( modeldb, start_dump_filename, & field_collection => & modeldb%fields%get_field_collection(target_collection_name) + call modeldb%io_contexts%get_io_context(context_dst, io_context) + call io_context%set_current() + + if (mode == mode_ics) then + prefix = 'checkpoint_' + else if (mode == mode_lbc) then + prefix = 'lbc_' + end if + do i = 1, num_fields call field_maker( field_collection, & config_list(i), & target_mesh, & - target_twod_mesh ) + target_twod_mesh, & + prefix ) end do + call modeldb%io_contexts%get_io_context(context_src, io_context) + call io_context%set_current() + ! Now finished with config_list, deallocate deallocate(config_list) diff --git a/applications/lfric2lfric/source/driver/lfric2lfric_regrid_mod.F90 b/applications/lfric2lfric/source/driver/lfric2lfric_regrid_mod.F90 new file mode 100644 index 000000000..fcab9323b --- /dev/null +++ b/applications/lfric2lfric/source/driver/lfric2lfric_regrid_mod.F90 @@ -0,0 +1,112 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2025 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief Performs regridding of a field collection +!> +module lfric2lfric_regrid_mod + + use constants_mod, only: str_def, i_def + use driver_modeldb_mod, only: modeldb_type + use field_parent_mod, only: field_parent_type + use field_mod, only: field_type + use field_collection_mod, only: field_collection_type + use field_collection_iterator_mod, only: & + field_collection_iterator_type + use log_mod, only: log_event, & + log_level_info, & + log_scratch_space + use model_clock_mod, only: model_clock_type + + !------------------------------------ + ! lfric2lfric modules + !------------------------------------ + use lfric2lfric_config_mod, only: regrid_method_map, & + regrid_method_lfric2lfric, & + regrid_method_oasis + use lfric2lfric_map_regrid_mod, only: lfric2lfric_map_regrid + use lfric2lfric_no_regrid_mod, only: lfric2lfric_no_regrid + use lfric2lfric_oasis_regrid_mod, only: lfric2lfric_oasis_regrid + + implicit none + + private + public lfric2lfric_regrid + +contains + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !> @brief Performs regridding of a field collection + !> @details Over one time step, all regridding is performed by algorithm + !! modules specific to the regrid method defined in the + !! configuration. + !! Fields to be regridded are extracted from the source field + !! collection. Corresponding source and target field pairs + !! are passed to the regridding algorithm, and written to fields + !! in the destination field collection. + !> @param [in,out] modeldb The structure that holds model + !! state + !> @param [in,out] oasis_clock Clock for OASIS exchanges + !> @param [in] source_fields Collection of fields to be regridded + !> @param [in] target_fields Collection of regridded fields + !> @param [in] regrid_method Method for regridding between the + !> source and destination meshes + subroutine lfric2lfric_regrid( modeldb, oasis_clock, & + source_fields, target_fields, regrid_method ) + + implicit none + + type(modeldb_type), intent(inout) :: modeldb + type(model_clock_type), allocatable, intent(inout) :: oasis_clock + type(field_collection_type), pointer, intent(in) :: source_fields + type(field_collection_type), pointer, intent(inout) :: target_fields + integer(kind=i_def), intent(in) :: regrid_method + + + type(field_collection_iterator_type) :: iter + + class(field_parent_type), pointer :: field => null() + type(field_type), pointer :: field_src => null() + type(field_type), pointer :: field_dst => null() + + character(len=str_def) :: field_name + + ! Main loop over fields to be processed + call iter%initialise(source_fields) + do + ! Locate the field to be processed in the field collections + if ( .not.iter%has_next() ) exit + field => iter%next() + field_name = field%get_name() + + call source_fields%get_field(field_name, field_src) + call target_fields%get_field(field_name, field_dst) + + write(log_scratch_space, '(A,A)') "Processing lfric field ", & + trim(field_name) + call log_event(log_scratch_space, log_level_info) + + ! Regrid source field depending on regrid method + select case (regrid_method) + case (regrid_method_map) + call lfric2lfric_map_regrid(field_dst, field_src) + + case (regrid_method_lfric2lfric) + write(log_scratch_space, '(A)') & + 'Regrid method lfric2lfric not implemented yet' + call log_event(log_scratch_space, log_level_info) + + call lfric2lfric_no_regrid(field_dst) + + case (regrid_method_oasis) +#ifdef MCT + call lfric2lfric_oasis_regrid(modeldb, oasis_clock, & + field_dst, field_src) +#endif + end select + end do + + end subroutine lfric2lfric_regrid + +end module lfric2lfric_regrid_mod diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 index 03fe1e587..d992e89b6 100644 --- a/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 +++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_field_init_mod.f90 @@ -22,9 +22,9 @@ module lfric2lfric_field_init_mod use lfric_xios_diag_mod, only: field_is_valid use lfric_xios_read_mod, only: read_field_generic, & checkpoint_read_xios - use space_from_metadata_mod, only: space_from_metadata use lfric_xios_write_mod, only: write_field_generic, & checkpoint_write_xios + use lfric2lfric_config_mod, only: mode_ics, mode_lbc use log_mod, only: log_event, & log_scratch_space, & log_level_info, & @@ -34,6 +34,7 @@ module lfric2lfric_field_init_mod use netcdf, only: nf90_inquire_variable, & nf90_inquire, & nf90_max_name + use space_from_metadata_mod, only: space_from_metadata implicit none @@ -54,13 +55,15 @@ module lfric2lfric_field_init_mod !> @param [out] num_fields Number of valid fields in the input file !> @param [out] config_list Vector of valid field names in the input file !> @param [in] file_name Input file to be checked - subroutine get_field_list(num_fields, config_list, file_name) + !> @param [in] prefix Variable name prefix + subroutine get_field_list(num_fields, config_list, file_name, prefix) implicit none integer(kind=i_def), intent(out) :: num_fields character(len=str_def), allocatable, intent(out) :: config_list(:) character(len=str_def), intent(in) :: file_name + character(len=nf90_max_name), intent(in) :: prefix ! Local variables type(lfric_ncdf_file_type) :: input_file integer(kind=i_def), allocatable :: varid_list(:) @@ -91,7 +94,7 @@ subroutine get_field_list(num_fields, config_list, file_name) varid_list(i), & name=var_name ) - if (field_is_valid('restart_'//trim(var_name))) then + if (field_is_valid(trim(prefix)//trim(var_name))) then num_fields = num_fields + 1 ! Increment counter config_list(num_fields) = trim(var_name) ! Add field to the config_list @@ -102,7 +105,7 @@ subroutine get_field_list(num_fields, config_list, file_name) else write(log_scratch_space, '(A)') & "Field not found in iodef file, skipping: "//& - "restart_"//trim(var_name) + trim(prefix)//trim(var_name) call log_event(log_scratch_space, log_level_trace) endif end do @@ -132,12 +135,13 @@ end subroutine get_field_list !! initalised on !> @param [in] twod_mesh The 2D mesh the field could be !! intialised on - subroutine field_maker(field_collection, field_name, mesh, twod_mesh) + subroutine field_maker(field_collection, field_name, mesh, twod_mesh, prefix) type(field_collection_type), pointer, intent(inout) :: field_collection character(len=*), intent(in) :: field_name type(mesh_type), pointer, intent(in) :: mesh type(mesh_type), pointer, intent(in) :: twod_mesh + character(len=nf90_max_name), intent(in) :: prefix ! Field object to initialise type(field_type) :: field @@ -157,10 +161,10 @@ subroutine field_maker(field_collection, field_name, mesh, twod_mesh) if ( .NOT. field_collection%field_exists(field_name) ) then ! Get function space from metadata - vector_space => space_from_metadata(trim("restart_"//field_name), & - 'Regridding', & - mesh_3d=mesh, & - mesh_2d=twod_mesh ) + vector_space => space_from_metadata(trim(prefix)//trim(field_name), & + 'Regridding', & + mesh_3d=mesh, & + mesh_2d=twod_mesh ) ! Initialise the field call field%initialise(vector_space=vector_space, & diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_file_init_mod.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_file_init_mod.f90 index c11ae829b..10adc1eb6 100644 --- a/applications/lfric2lfric/source/initialisation/lfric2lfric_file_init_mod.f90 +++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_file_init_mod.f90 @@ -8,28 +8,27 @@ !! and formats it so that it can be passed to the infrastructure. module lfric2lfric_file_init_mod - use constants_mod, only : i_def, & - str_max_filename - use driver_modeldb_mod, only : modeldb_type - use file_mod, only : FILE_MODE_READ, & - FILE_MODE_WRITE - use files_config_mod, only : checkpoint_stem_name, & - diag_stem_name, & - start_dump_filename - use io_config_mod, only : diagnostic_frequency, & - checkpoint_write, & - checkpoint_read, & - write_diag, & - use_xios_io - use lfric_xios_file_mod, only : lfric_xios_file_type, & - OPERATION_TIMESERIES - use lfric2lfric_config_mod, only : dst_ancil_directory, & - dst_orography_mean_ancil_path, & - src_ancil_directory, & - src_orography_mean_ancil_path - use linked_list_mod, only : linked_list_type - use orography_config_mod, only : orog_init_option, & - orog_init_option_ancil + use constants_mod, only: i_def, & + str_max_filename + use driver_modeldb_mod, only: modeldb_type + use file_mod, only: FILE_MODE_READ, & + FILE_MODE_WRITE + use io_config_mod, only: diagnostic_frequency, & + checkpoint_write, & + checkpoint_read, & + write_diag, & + use_xios_io + use lfric_xios_file_mod, only: lfric_xios_file_type, & + OPERATION_TIMESERIES + use lfric2lfric_config_mod, only: dst_ancil_directory, & + dst_orography_mean_ancil_path, & + src_ancil_directory, & + src_orography_mean_ancil_path, & + mode_ics, mode_lbc + use linked_list_mod, only: linked_list_type + use namelist_mod, only: namelist_type + use orography_config_mod, only: orog_init_option, & + orog_init_option_ancil implicit none @@ -40,7 +39,8 @@ module lfric2lfric_file_init_mod !> @brief Sets up source I/O configuration. !> @details Initialises the file list for the source I/O context, using the - !! start_dump_filename extracted from the `files` namelist. + !! start_dump_filename extracted from the `files` namelist, or the + !! source_file_lbc extracted from the `lfric2lfric` namelist. !> @param [out] files_list The list of I/O files. !> @param [in,out] modeldb Required by init_io. subroutine init_lfric2lfric_src_files( files_list, modeldb ) @@ -50,26 +50,41 @@ subroutine init_lfric2lfric_src_files( files_list, modeldb ) type(linked_list_type), intent(out) :: files_list type(modeldb_type), optional, intent(inout) :: modeldb + type(namelist_type), pointer :: lfric2lfric_nml + type(namelist_type), pointer :: files_nml + + integer(kind=i_def) :: mode + character(len=str_max_filename) :: start_dump_filename + character(len=str_max_filename) :: source_file_lbc character(len=str_max_filename) :: src_ancil_fname if( use_xios_io ) then - ! Set up diagnostic writing info - if( write_diag ) then - ! Setup diagnostic output file - call files_list%insert_item( & - lfric_xios_file_type( trim( diag_stem_name ), & - xios_id="lfric_diag", & - io_mode=FILE_MODE_WRITE, & + lfric2lfric_nml => modeldb%configuration%get_namelist('lfric2lfric') + call lfric2lfric_nml%get_value( 'mode', mode ) + + files_nml => modeldb%configuration%get_namelist('files') + if (mode == mode_ics) then + call files_nml%get_value( 'start_dump_filename', start_dump_filename ) + + ! Setup checkpoint reading context information + call files_list%insert_item( & + lfric_xios_file_type( trim(start_dump_filename), & + xios_id="lfric_checkpoint_read", & + io_mode=FILE_MODE_READ ) ) + + else if (mode == mode_lbc) then + call lfric2lfric_nml%get_value( 'source_file_lbc', source_file_lbc ) + + ! Setup lbc source reading context information + call files_list%insert_item( & + lfric_xios_file_type( trim(source_file_lbc), & + xios_id="lfric_lbc_read", & + io_mode=FILE_MODE_READ, & + operation=OPERATION_TIMESERIES, & freq=diagnostic_frequency) ) endif - ! Setup checkpoint reading context information - call files_list%insert_item( & - lfric_xios_file_type( trim(start_dump_filename), & - xios_id="lfric_checkpoint_read", & - io_mode=FILE_MODE_READ ) ) - ! Setup orography ancillary file if ( orog_init_option == orog_init_option_ancil ) then ! Set orography ancil filename from namelist @@ -98,20 +113,52 @@ subroutine init_lfric2lfric_dst_files( files_list, modeldb ) type(modeldb_type), optional, intent(inout) :: modeldb ! Local variables - integer(kind=i_def), parameter :: checkpoint_frequency = 1_i_def + type(namelist_type), pointer :: lfric2lfric_nml + type(namelist_type), pointer :: files_nml + integer(kind=i_def), parameter :: checkpoint_frequency = 1_i_def + integer(kind=i_def) :: mode character(len=str_max_filename) :: dst_ancil_fname + character(len=str_max_filename) :: checkpoint_stem_name + character(len=str_max_filename) :: diag_stem_name if( use_xios_io ) then - ! Setup checkpoint reading context information - if ( checkpoint_write ) then + lfric2lfric_nml => modeldb%configuration%get_namelist('lfric2lfric') + call lfric2lfric_nml%get_value( 'mode', mode ) + + files_nml => modeldb%configuration%get_namelist('files') + ! Set up diagnostic writing info + if( write_diag ) then + call files_nml%get_value( 'diag_stem_name', diag_stem_name ) + + ! Setup diagnostic output file + call files_list%insert_item( & + lfric_xios_file_type( trim( diag_stem_name ), & + xios_id="lfric_diag", & + io_mode=FILE_MODE_WRITE, & + freq=diagnostic_frequency) ) + endif + + if (mode == mode_ics) then + ! Setup checkpoint writing context information + if ( checkpoint_write ) then + call files_nml%get_value( 'checkpoint_stem_name', checkpoint_stem_name ) + call files_list%insert_item( & lfric_xios_file_type( trim( checkpoint_stem_name ), & xios_id="lfric_checkpoint_write", & io_mode=FILE_MODE_WRITE, & - operation=OPERATION_TIMESERIES, & freq=checkpoint_frequency ) ) + end if + else if (mode == mode_lbc) then + ! Setup lbc writing context information + call files_list%insert_item( & + lfric_xios_file_type( "lfric2lfric_lbc", & + xios_id="lfric_lbc_write", & + io_mode=FILE_MODE_WRITE, & + operation=OPERATION_TIMESERIES, & + freq=diagnostic_frequency ) ) endif ! Setup orography ancillary file diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 index 108104c11..83f7f6c1f 100644 --- a/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 +++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_infrastructure_mod.X90 @@ -14,6 +14,7 @@ module lfric2lfric_infrastructure_mod use add_mesh_map_mod, only: assign_mesh_maps use blend_orography_alg_mod, only: blend_orography + use check_configuration_mod, only: get_required_stencil_depth use constants_mod, only: str_def, r_def, i_def, l_def, r_second use create_mesh_mod, only: create_extrusion, & create_mesh @@ -21,7 +22,6 @@ module lfric2lfric_infrastructure_mod use driver_fem_mod, only: init_fem use driver_io_mod, only: init_io, & filelist_populator - use check_configuration_mod, only: get_required_stencil_depth use extrusion_mod, only: extrusion_type, & uniform_extrusion_type, & prime_extrusion, & @@ -68,7 +68,7 @@ module lfric2lfric_infrastructure_mod use lfric2lfric_init_mesh_mod, only: init_mesh use lfric2lfric_check_conf_mod, only: lfric2lfric_check_configuration use lfric2lfric_file_init_mod, only: init_lfric2lfric_dst_files, & - init_lfric2lfric_src_files + init_lfric2lfric_src_files use lfric2lfric_init_mod, only: init_lfric2lfric use lfric2lfric_init_coupler_mod,only: lfric2lfric_init_coupler_src, & lfric2lfric_init_coupler_dst, & @@ -93,11 +93,13 @@ module lfric2lfric_infrastructure_mod method_um_L120_99t_21s_40km, & method_um_L140_122t_18s_40km, & method_um_L70_50t_20s_80km - use lfric2lfric_config_mod, only: regrid_method_oasis, & + use lfric2lfric_config_mod, only: mode_ics, mode_lbc, & regrid_method_lfric2lfric, & regrid_method_map, & - source_geometry_spherical, & - source_geometry_planar + regrid_method_oasis, & + source_geometry_planar, & + source_geometry_spherical + implicit none @@ -120,12 +122,15 @@ contains !! checks the configuration namelist, initialises meshes, !! extrusions, XIOS contexts and files, field collections and !! fields. - !> @param [in,out] modeldb The structure holding model state - subroutine initialise_infrastructure( modeldb ) + !> @param [in,out] modeldb The structure holding model state + !> @param [in,out] oasis_clock Clock for OASIS exchanges + subroutine initialise_infrastructure( modeldb, oasis_clock ) implicit none type(modeldb_type), intent(inout) :: modeldb + type(model_clock_type), allocatable, & + intent(inout) :: oasis_clock ! Coordinate field type(field_type), pointer :: chi(:) @@ -133,12 +138,12 @@ contains type(field_type) :: surface_altitude_dst type(field_type) :: surface_altitude_src type(field_type) :: surface_altitude_src_on_dst - type(field_type), pointer :: src_field - type(field_type), pointer :: dst_field + type(field_type), pointer :: src_field + type(field_type), pointer :: dst_field type(inventory_by_mesh_type), pointer :: chi_inventory type(inventory_by_mesh_type), pointer :: panel_id_inventory - type(function_space_type), pointer :: vector_space + type(function_space_type), pointer :: vector_space !----------------------- ! Mesh Pointers @@ -164,13 +169,12 @@ contains character(len=str_def) :: mesh_names(2) character(len=str_def), allocatable :: twod_names(:) character(len=str_def) :: start_dump_filename + character(len=str_def) :: source_file_lbc ! lfric2lfric namelist parameters - integer(kind=i_def) :: origin_domain - integer(kind=i_def) :: target_domain - - integer(kind=i_def) :: stencil_depth + integer(kind=i_def) :: stencil_depth(1) integer(kind=i_def) :: source_geometry + integer(i_def) :: mode integer(i_def) :: regrid_method real(kind=r_def) :: domain_bottom real(kind=r_def) :: scaled_radius @@ -187,21 +191,20 @@ contains integer(kind=i_def), parameter :: dst = 1 integer(kind=i_def), parameter :: src = 2 - type(coupling_type), pointer :: coupling_ptr - - type(field_collection_type), pointer :: cpl_snd_2d - type(field_collection_type), pointer :: cpl_rcv_2d - integer(i_def), pointer :: local_index(:) - type(coupler_exchange_2d_type) :: coupler_exchange_2d - integer(i_def) :: ierror - logical(l_def) :: is_running + type(coupling_type), pointer :: coupling_ptr + type(field_collection_type), pointer :: cpl_snd_2d + type(field_collection_type), pointer :: cpl_rcv_2d + integer(kind=i_def), pointer :: local_index(:) + type(coupler_exchange_2d_type) :: coupler_exchange_2d + integer(kind=i_def) :: ierror + logical(kind=l_def) :: is_running !------------------------ ! XIOS contexts !------------------------ ! Pointer for subroutines used in init_io - procedure(filelist_populator), pointer :: files_init_ptr - procedure(callback_clock_arg), pointer :: before_close => null() + procedure(filelist_populator), pointer :: files_init_ptr + procedure(callback_clock_arg), pointer :: before_close ! Source context pointer and temporary context for setup type(lfric_xios_context_type) :: tmp_io_context_src @@ -227,13 +230,12 @@ contains ! Check lfric2lfric configuration settings are allowed call lfric2lfric_check_configuration( lfric2lfric_nml ) - call lfric2lfric_nml%get_value( 'origin_domain', origin_domain ) + call lfric2lfric_nml%get_value( 'mode', mode ) call lfric2lfric_nml%get_value( 'regrid_method', regrid_method ) call lfric2lfric_nml%get_value( 'destination_mesh_name', & mesh_names(dst) ) call lfric2lfric_nml%get_value( 'source_mesh_name', & mesh_names(src) ) - call lfric2lfric_nml%get_value( 'target_domain', target_domain ) call lfric2lfric_nml%get_value( 'source_geometry', source_geometry ) call files_nml%get_value( 'start_dump_filename', start_dump_filename ) call finite_element_nml%get_value( 'element_order_h', element_order_h) @@ -315,7 +317,7 @@ contains !----------------------------------------------------------------------- ! Create the required meshes !----------------------------------------------------------------------- - stencil_depth = get_required_stencil_depth() + stencil_depth = 2 call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & @@ -340,10 +342,9 @@ contains panel_id_inventory => get_panel_id_inventory() call init_fem( mesh_collection, chi_inventory, panel_id_inventory ) - !----------------------------------------------------------------------- - ! Create the coordinates fields !----------------------------------------------------------------------- ! Assign pointers to the correct meshes + !----------------------------------------------------------------------- mesh_src => mesh_collection%get_mesh(trim(mesh_names(src))) twod_mesh_src => mesh_collection%get_mesh(trim(twod_names(src))) mesh_dst => mesh_collection%get_mesh(trim(mesh_names(dst))) @@ -379,23 +380,16 @@ contains call modeldb%io_contexts%get_io_context(context_dst, io_context_dst) - ! Must call advance to align IO context clock with iodef and file - ! output frequency - call advance(io_context_dst, modeldb%clock) - !======================================================================= - ! Initialise the clock + ! Initialise the OASIS clock !======================================================================= - ! lfric2lfric doesn't use a typical model clock. To make it more flexible, - ! fields (which can be multi-level and multi data) are broken down into - ! simple 2d fields, which are then passed through regridding. If Oasis is - ! being used, it can only provide one coupling per clock tick - so we + ! If Oasis is used, it can only provide one coupling per clock tick - so we ! introduce a pseudo clock, that ticks every coupling, rather than every ! timestep. We don't know how many 2d fields will be passed through the - ! coupler, yet, so set the upper limit to "huge" to support everything - modeldb%clock = model_clock_type(1_i_def, huge(1_i_def), & + ! coupler yet, so set the upper limit to "huge" to support everything + oasis_clock = model_clock_type(1_i_def, huge(1_i_def), & 1.0_r_second, 0.0_r_second) - is_running = modeldb%clock%tick() + is_running = oasis_clock%tick() !======================================================================= ! Initialise destination orography @@ -437,6 +431,7 @@ contains call panel_id_inventory%get_field(mesh_src, panel_id) ! Using correct chi and panel_id, initialise xios context for source mesh + nullify( before_close ) call io_context_src%initialise_xios_context( modeldb%mpi%get_comm(), & chi, & panel_id, & @@ -444,10 +439,6 @@ contains modeldb%calendar, & before_close ) - ! Must call advance to align IO context clock with iodef and file - ! output frequency - call advance(io_context_src, modeldb%clock) - !======================================================================= ! Initialise source orography !======================================================================= @@ -470,9 +461,18 @@ contains !======================================================================= ! Create and initialise prognostic fields !======================================================================= - call init_lfric2lfric( modeldb, start_dump_filename, & - source_collection_name, mesh_src, twod_mesh_src, & - target_collection_name, mesh_dst, twod_mesh_dst ) + if (mode == mode_ics) then + call init_lfric2lfric( modeldb, context_src, context_dst, & + start_dump_filename, mode, & + source_collection_name, mesh_src, twod_mesh_src, & + target_collection_name, mesh_dst, twod_mesh_dst ) + else if (mode == mode_lbc) then + call lfric2lfric_nml%get_value( 'source_file_lbc', source_file_lbc ) + call init_lfric2lfric( modeldb, context_src, context_dst, & + source_file_lbc, mode, & + source_collection_name, mesh_src, twod_mesh_src, & + target_collection_name, mesh_dst, twod_mesh_dst ) + end if !======================================================================= ! Initialize variables for each regrid method @@ -538,7 +538,7 @@ contains coupling_ptr => get_coupling_from_collection(modeldb%values, "coupling" ) local_index => coupling_ptr%get_local_index() call coupler_exchange_2d%initialise(src_field, local_index) - call coupler_exchange_2d%set_time(modeldb%clock) + call coupler_exchange_2d%set_time(oasis_clock) call coupler_exchange_2d%copy_from_lfric(ierror) call coupler_exchange_2d%clear() @@ -546,12 +546,12 @@ contains coupling_ptr => get_coupling_from_collection(modeldb%values, "coupling_dst" ) local_index => coupling_ptr%get_local_index() call coupler_exchange_2d%initialise(dst_field, local_index) - call coupler_exchange_2d%set_time(modeldb%clock) + call coupler_exchange_2d%set_time(oasis_clock) call coupler_exchange_2d%copy_to_lfric(ierror) call coupler_exchange_2d%clear() ! Done the first coupling - so advance the pseudo-clock - is_running = modeldb%clock%tick() + is_running = oasis_clock%tick() ! Copy the horizontally regridded src orography into dst orography mesh ! ----------------------------------------------------------- diff --git a/applications/lfric2lfric/source/initialisation/lfric2lfric_init_mesh.f90 b/applications/lfric2lfric/source/initialisation/lfric2lfric_init_mesh.f90 index f1134fce5..3b20a554e 100644 --- a/applications/lfric2lfric/source/initialisation/lfric2lfric_init_mesh.f90 +++ b/applications/lfric2lfric/source/initialisation/lfric2lfric_init_mesh.f90 @@ -75,7 +75,8 @@ module lfric2lfric_init_mesh_mod !> @param[in] total_ranks Total number of MPI ranks in this job. !> @param[in] mesh_names Mesh names to load from the mesh input file(s). !> @param[in] extrusion Extrusion object to be applied to meshes. -!> @param[in] stencil_depth Required stencil depth for the application. +!> @param[in] stencil_depths_in Required stencil depth for the application +!! for each mesh. !> @param[in] regrid_method Apply check for even partitions with the !> configured partition strategy if the !> regridding method is 'map'. @@ -85,7 +86,7 @@ subroutine init_mesh( configuration, & local_rank, total_ranks, & mesh_names, & extrusion, & - stencil_depth, & + stencil_depths_in, & regrid_method ) implicit none @@ -97,7 +98,7 @@ subroutine init_mesh( configuration, & integer(kind=i_def), intent(in) :: total_ranks character(len=*), intent(in) :: mesh_names(2) class(extrusion_type), intent(in) :: extrusion - integer(kind=i_def), intent(in) :: stencil_depth + integer(kind=i_def), intent(in) :: stencil_depths_in(:) integer(kind=i_def), intent(in) :: regrid_method ! Parameters @@ -123,7 +124,9 @@ subroutine init_mesh( configuration, & integer(kind=i_def) :: mesh_selection(2) ! Local variables + integer(kind=i_def) :: i character(len=str_max_filename) :: mesh_file(2) + integer(kind=i_def) :: stencil_depths(2) procedure(partitioner_interface), pointer :: partitioner_src => null() procedure(partitioner_interface), pointer :: partitioner_dst => null() @@ -173,6 +176,22 @@ subroutine init_mesh( configuration, & call log_event(log_scratch_space, log_level_error) end if + ! Set up stencil depths + if ( size(stencil_depths) == 1 ) then + ! Single stencil depth specified, apply to all meshes + do i = 1, size(mesh_names) + stencil_depths(i) = stencil_depths_in(1) + end do + else if ( size(stencil_depths) == size(mesh_names) ) then + ! Stencil depths specified per mesh + stencil_depths(:) = stencil_depths_in(:) + else + write(log_scratch_space, '(A)') & + 'Number of stencil depths specified does not '// & + 'match number of requested meshes.' + call log_event(log_scratch_space, log_level_error) + end if + !=========================================================================== ! Create local mesh objects: @@ -231,8 +250,8 @@ subroutine init_mesh( configuration, & ! meshes are suitable for the supplied application ! configuration. !=========================================================== - call check_local_mesh( configuration, & - stencil_depth, & + call check_local_mesh( configuration, & + stencil_depths, & mesh_names ) ! Load and assign mesh maps. @@ -289,7 +308,6 @@ subroutine init_mesh( configuration, & decomposition_dst, & partitioner_dst ) - ! Read in all global meshes from input file !=========================================================== if (mesh_file(dst) == mesh_file(src)) then @@ -304,15 +322,15 @@ subroutine init_mesh( configuration, & call create_local_mesh( mesh_names(dst:dst), & local_rank, total_ranks, & decomposition_dst, & - stencil_depth, & - generate_inner_halos(dst), & + stencil_depths, & + generate_inner_halos(dst), & partitioner_dst ) call create_local_mesh( mesh_names(src:src), & local_rank, total_ranks, & decomposition_src, & - stencil_depth, & - generate_inner_halos(src), & + stencil_depths, & + generate_inner_halos(src), & partitioner_src ) ! Read in the global intergrid mesh mappings, diff --git a/applications/lfric2lfric/source/lfric2lfric.F90 b/applications/lfric2lfric/source/lfric2lfric.F90 index 1f09afac8..760008004 100644 --- a/applications/lfric2lfric/source/lfric2lfric.F90 +++ b/applications/lfric2lfric/source/lfric2lfric.F90 @@ -14,7 +14,7 @@ program lfric2lfric - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use constants_mod, only: precision_real use driver_collections_mod, only: init_collections, final_collections use driver_config_mod, only: init_config, final_config @@ -29,9 +29,9 @@ program lfric2lfric log_level_trace, & log_scratch_space use lfric_mpi_mod, only: global_mpi - use lfric2lfric_mod, only: lfric2lfric_required_namelists use lfric2lfric_driver_mod, only: initialise, run, finalise + use model_clock_mod, only: model_clock_type implicit none @@ -45,6 +45,10 @@ program lfric2lfric ! Coupler objects type(coupling_type) :: coupler #endif + ! Clock for OASIS exchanges + type(model_clock_type), allocatable :: oasis_clock + + call parse_command_line( filename ) call modeldb%configuration%initialise( program_name, table_len=10 ) @@ -65,7 +69,6 @@ program lfric2lfric call modeldb%values%add_key_value('coupling_dst', coupler) #endif call init_comm( program_name, modeldb ) - call get_initial_filename( filename ) call init_config( filename, lfric2lfric_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), program_name ) @@ -79,9 +82,9 @@ program lfric2lfric call modeldb%io_contexts%initialise(program_name, 100) call log_event( 'Initialising ' // program_name // ' ...', log_level_trace ) - call initialise( modeldb ) + call initialise( modeldb, oasis_clock ) - call run( modeldb ) + call run( modeldb, oasis_clock ) call log_event( 'Finalising ' // program_name // ' ...', log_level_trace ) call finalise( program_name, modeldb ) diff --git a/applications/lfric_atm/Makefile b/applications/lfric_atm/Makefile index 98f689dee..7457acec7 100644 --- a/applications/lfric_atm/Makefile +++ b/applications/lfric_atm/Makefile @@ -75,7 +75,7 @@ build: export BIN_DIR ?= $(PROJECT_DIR)/bin build: export CXX_LINK = YES build: export PROGRAMS := $(basename $(notdir $(shell find source -maxdepth 1 -name '*.[Ff]90' -exec egrep -l "^\s*program" {} \;))) build: export PROJECT = lfric_atm -build: export SCRATCH_DIR := $(WORKING_DIR)/../physics_scratch +build: export SCRATCH_DIR := $(WORKING_DIR)/.. build: export WORKING_DIR := $(WORKING_DIR) build: export LDFLAGS_GROUPS = OPENMP @@ -151,10 +151,15 @@ build: ALWAYS PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" + $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute_pass.mk \ + SOURCE_DIR=$(WORKING_DIR) \ + OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute.mk \ SOURCE_DIR=$(WORKING_DIR) \ OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" $(call MESSAGE,=========================================================) diff --git a/applications/lfric_atm/build/compile_options.mk b/applications/lfric_atm/build/compile_options.mk index 143f09ae6..842a61d60 100644 --- a/applications/lfric_atm/build/compile_options.mk +++ b/applications/lfric_atm/build/compile_options.mk @@ -13,7 +13,8 @@ $(info UM physics specific compile options) include $(PROJECT_DIR)/build/fortran/$(FORTRAN_COMPILER).mk -science/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) +casim/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) +ukca/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) jules/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) socrates/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) legacy/%.o: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) diff --git a/applications/lfric_atm/build/psyclone_transmute_file_list.mk b/applications/lfric_atm/build/psyclone_transmute_file_list.mk index 215126425..589731269 100644 --- a/applications/lfric_atm/build/psyclone_transmute_file_list.mk +++ b/applications/lfric_atm/build/psyclone_transmute_file_list.mk @@ -14,21 +14,44 @@ # Choose which files to Pre-proccess and PSyclone from physics_schemes / other source (e.g. UKCA) -export PSYCLONE_PHYSICS_FILES = mphys_kernel_mod \ +export PSYCLONE_PHYSICS_FILES = \ + bl_lsp \ + bl_diags_mod \ bm_tau_kernel_mod \ + btq_int \ + conv_gr_kernel_mod \ + ex_flux_tq \ + ex_flux_uv \ + fm_drag \ gw_ussp_mod \ + imp_mix \ + jules_exp_kernel_mod \ + jules_extra_kernel_mod \ + jules_imp_kernel_mod \ + kmkh \ + kmkhz_9c_wtrac \ lw_kernel_mod \ + mphys_kernel_mod \ + pc2_bl_forced_cu \ + pc2_bm_initiate \ + pc2_initiation_ctl \ pc2_initiation_kernel_mod \ pc2_conv_coupling_kernel_mod \ sw_kernel_mod \ - ukca_aero_ctl \ - ukca_abdulrazzak_ghan \ - ukca_chemistry_ctl_full_mod \ - ukca_main1-ukca_main1 \ sw_rad_tile_kernel_mod \ - jules_imp_kernel_mod \ - jules_exp_kernel_mod \ - jules_extra_kernel_mod + tr_mix \ + ukca_aero_ctl \ + ukca_chemistry_ctl_full_mod \ + ukca_main1-ukca_main1 + + +##### TRANSMUTE_INCLUDE_METHOD specify_include ##### + +# List to use PSyclone explicitly without any opt script +# This will remove hand written (OMP) directives in the source +# Used by both methods, specify_include and specify_exclude +export PSYCLONE_PASS_NO_SCRIPT = ukca_abdulrazzak_ghan + ##### TRANSMUTE_INCLUDE_METHOD specify_exclude ##### # For GPU, we may want to use more generic local.py transformation scripts and psyclone by directory. diff --git a/applications/lfric_atm/example/configuration.nml b/applications/lfric_atm/example/configuration.nml index 5301f68ed..d46ff98c4 100644 --- a/applications/lfric_atm/example/configuration.nml +++ b/applications/lfric_atm/example/configuration.nml @@ -335,6 +335,9 @@ write_minmax_tseries=.false., l_var_rainfrac=.true., l_hydrology=.true., / +&jules_model_environment_lfric +l_jules_parent='lfric', +/ &jules_nvegparm albsnc_nvg_io=0.4,0.8,0.8,0.8, albsnf_nvg_io=0.18,0.12,-1.0,0.75, @@ -407,12 +410,31 @@ rho_snow_fresh=109.0, unload_rate_u=2.31e-6,2.31e-6,0.0,0.0,0.0, / &jules_surface +all_tiles='off', +beta1=0.83, +beta2=0.93, +beta_cnv_bl=0.04, cor_mo_iter='improved', +fd_hill_option='capped_lowhill', fd_stability_dep='none', formdrag='dist_drag', +fwe_c3=0.5, +fwe_c4=20000.0, +hleaf=5.7e4, +hwood=1.1e4, +i_modiscopt='on', +iscrntdiag='decoupled_trans', l_anthrop_heat_src=.false., +l_epot_corr=.true., +l_elev_land_ice=.false., +l_elev_lw_down=.false., +l_flake_model=.false., +l_land_ice_imp=.true., +l_mo_buoyancy_calc=.true., +l_point_data=.false., l_urban2t=.false., l_vary_z0m_soil=.true., +orog_drag_param=0.15, srf_ex_cnv_gust=.true., / &jules_soil @@ -602,6 +624,7 @@ tau_u=0.55, &transport adjust_theta=.true., adjust_theta_above=30000.0, +adjust_tracer_equation=.false. adjust_vhv_wind=.false. ageofair_reset_level=10, broken_w2_projection=.false., diff --git a/applications/lfric_atm/example/iodef.xml b/applications/lfric_atm/example/iodef.xml index fc0a6ddb2..96653326d 100644 --- a/applications/lfric_atm/example/iodef.xml +++ b/applications/lfric_atm/example/iodef.xml @@ -133,7 +133,7 @@ performance - 1.0 + 1.0 diff --git a/applications/lfric_atm/metadata/field_def_diags.xml b/applications/lfric_atm/metadata/field_def_diags.xml index 007ee86df..a17d884f9 100644 --- a/applications/lfric_atm/metadata/field_def_diags.xml +++ b/applications/lfric_atm/metadata/field_def_diags.xml @@ -43,6 +43,8 @@ + + zoomed__orography diff --git a/applications/lfric_atm/metadata/field_def_initial_diags.xml b/applications/lfric_atm/metadata/field_def_initial_diags.xml index 707675af2..b91c8aed1 100644 --- a/applications/lfric_atm/metadata/field_def_initial_diags.xml +++ b/applications/lfric_atm/metadata/field_def_initial_diags.xml @@ -21,6 +21,8 @@ + + diff --git a/applications/lfric_atm/optimisation/azngarch-sandbox/psykal/algorithm/conv_gr_alg_mod.py b/applications/lfric_atm/optimisation/azngarch-sandbox/psykal/algorithm/conv_gr_alg_mod.py new file mode 100644 index 000000000..8c66e13ad --- /dev/null +++ b/applications/lfric_atm/optimisation/azngarch-sandbox/psykal/algorithm/conv_gr_alg_mod.py @@ -0,0 +1,31 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- + +""" +PSyclone transformation script for the LFRic (Dynamo0p3) API to apply +colouring and redundant computation to the level-1 halo for +the initialisation built-ins generically. + +""" + +from psyclone_tools import ( + redundant_computation_setval, + colour_loops, + view_transformed_schedule, +) + + +def trans(psyir): + """ + Applies PSyclone colouring and redundant computation transformations. + + :param psyir: the PSyIR of the PSy-layer. + :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` + + """ + redundant_computation_setval(psyir) + colour_loops(psyir) + view_transformed_schedule(psyir) diff --git a/applications/lfric_atm/optimisation/azngarch-sandbox/transmute/global.py b/applications/lfric_atm/optimisation/azngarch-sandbox/transmute/global.py new file mode 100644 index 000000000..3689181e3 --- /dev/null +++ b/applications/lfric_atm/optimisation/azngarch-sandbox/transmute/global.py @@ -0,0 +1,9 @@ +############################################################################## +# Copyright (c) 2025, Met Office, on behalf of HMSO and Queen's Printer +# For further details please refer to the file LICENCE.original which you +# should have received as part of this distribution. +############################################################################## +''' +Placeholder script to ensure site is unaffected by changes. +Owners of site target should update this as required. +''' \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/azngarch-sandbox/transmute/kernel/conv_gr_kernel_mod.py b/applications/lfric_atm/optimisation/azngarch-sandbox/transmute/kernel/conv_gr_kernel_mod.py new file mode 100644 index 000000000..7a704a47f --- /dev/null +++ b/applications/lfric_atm/optimisation/azngarch-sandbox/transmute/kernel/conv_gr_kernel_mod.py @@ -0,0 +1,387 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +""" +PSyclone script for applying OpenMP transformations specific to the +Gregory-Rowntree convection kernel. +""" +import logging + +from psyclone.psyir.nodes import ( + Call, + Loop, + Node, + OMPParallelDoDirective, + Reference, + Routine, + OMPParallelDirective, + OMPDoDirective, +) +from psyclone.transformations import ( + OMPParallelLoopTrans, + TransformationError, +) + +from transmute_psytrans.transmute_functions import ( + first_priv_red_init, + get_compiler, + add_omp_parallel_region, +) + +logger = logging.getLogger(__name__) + + +def trans(psyir: Routine): + """ + Apply PSyClone OpenMP directives + + Transformation takes the following steps: + - Add OMPParallelDirective around marked loops with OMPParallelTrans + - Add OMPDoDirective to loops within the parallel regions with OMPLoopTrans + - Add OMPParallelDoDirective to loops outside the parallel regions with OMPParallelLoopTrans + + Special treatment required for the loop containing glue_conv_6a. + """ + + # Transformations + omp_trans_parallel_loop_static = OMPParallelLoopTrans( + omp_schedule="static", omp_directive="paralleldo" + ) + omp_trans_parallel_loop_dynamic = OMPParallelLoopTrans( + omp_schedule="dynamic", omp_directive="paralleldo" + ) + + default_trans_options = {"collapse": True} + if get_compiler() == "cce": + default_trans_options["collapse"] = False + loop_trans_options = default_trans_options | {"node-type-check": False} + + for routine in psyir.walk(Routine): + # Identify large parallel region + try: + callnumber_loop = next(filter(is_callnumber_loop, routine.children)) + except StopIteration: + logger.error("Call-number loop not found in routine.") + return + first_loop = next( + filter(lambda node: isinstance(node, Loop), routine.children) + ) + + case_loop = next( + filter( + lambda loop: "ntra_fld" in str(loop.stop_expr), + routine.walk(Loop), + ), + None, + ) + + loops_to_ignore = [case_loop] + + # Ignore nested wtrac loops except inner-most (i) loops to agree with old script + for loop in filter(is_wtrac_loop, routine.walk(Loop)): + loops_to_ignore.extend( + inner_loop + for inner_loop in loop.walk(Loop) + if inner_loop.variable.name != "i" + ) + + add_omp_parallel_region( + first_loop, + callnumber_loop, + end_offset=-2, + ignore_loops=loops_to_ignore, + loop_trans_options=loop_trans_options, + ) + + # Identify extra parallel regions (loops inside callnumber loop, up to numseg) + try: + numseg_loop = next(filter(is_numseg_loop, routine.walk(Loop))) + except StopIteration: + logger.error("Numseg loop not found in call-number loop.") + return + + callnumber_nested_loop = callnumber_loop.loop_body.children[0] + + add_omp_parallel_region( + callnumber_nested_loop, + numseg_loop, + end_offset=-2, + loop_trans_options=loop_trans_options, + ) + + # Special treatment of numseg loop for parallel do + + # Add "pure" property to specific symbols + for call in numseg_loop.walk(Call): + if call.routine.symbol.name in ["glue_conv_6a", "log_event"]: + call.routine.symbol.is_pure = True + try: + omp_trans_parallel_loop_dynamic.apply( + numseg_loop, + options=loop_trans_options, + ) + except TransformationError as e: + logger.warning(e) + + for loop in routine.walk(Loop): + # Identify each loop in the routine and add OMPParallelDoDirective to outer loops + + # Ignore specific outer loops (their inner loops will still be transformed) + if loop.variable.name in ["call_number"]: + continue + + # Don't attempt to nest parallel directives + if ( + loop.ancestor(OMPParallelDoDirective) is not None + or loop.ancestor(OMPDoDirective) is not None + or loop.ancestor(OMPParallelDirective) is not None + ): + continue + + # Main transformations: + # Add OMPParallelDoDirective outside OMPParallelDirective regions + try: + omp_trans_parallel_loop_static.apply( + loop, + options=default_trans_options + | { + "ignore_dependencies_for": ( + ignore_dependencies_block2_after_numseg + + ignore_dependencies_block3 + ), + }, + ) + except TransformationError as e: + logger.warning(e) + + # Fix for firstprivate initialisation bug with CCE + if get_compiler() == "cce": + first_private_list = ["k", "conv_active", "orig_value"] + for node in routine.children: + if isinstance(node, OMPParallelDirective): + first_priv_red_init(node, first_private_list) + break + + +def is_numseg_loop(node: Node): + """ + Check if node is the num_seg loop: "do i = 1, num_seg" + """ + return ( + isinstance(node, Loop) + and node.variable.name == "i" + and any(ref.name == "num_seg" for ref in node.stop_expr.walk(Reference)) + ) + + +def is_callnumber_loop(node: Node): + """ + Check if node is the call_number loop: "do call_number = 1, n_conv_calls" + """ + return ( + isinstance(node, Loop) + and node.variable.name == "call_number" + and any( + ref.name == "n_conv_calls" for ref in node.stop_expr.walk(Reference) + ) + ) + + +def is_wtrac_loop(node: Node): + """ + Check if node is a n_wtrac loop: "do _ = 1, n_wtrac, 1" + """ + return isinstance(node, Loop) and any( + ref.name == "n_wtrac" for ref in node.stop_expr.walk(Reference) + ) + + +ignore_dependencies_block2_after_numseg = [ + "conv_rain", + "conv_snow", + "cca_2d", + "cape_diluted", + "lowest_cca_2d", + "deep_in_col", + "shallow_in_col", + "mid_in_col", + "freeze_level", + "deep_prec", + "shallow_prec", + "mid_prec", + "deep_term", + "cape_timescale", + "deep_cfl_limited", + "mid_cfl_limited", + "deep_tops", + "dt_conv", + "dmv_conv", + "dmcl_conv", + "dms_conv", + "massflux_up", + "massflux_down", + "conv_rain_3d", + "conv_snow_3d", + "entrain_up", + "entrain_down", + "detrain_up", + "detrain_down", + "dd_dt", + "dd_dq", + "deep_massflux", + "deep_dt", + "deep_dq", + "shallow_massflux", + "shallow_dt", + "shallow_dq", + "mid_massflux", + "mid_dt", + "mid_dq", + "cca_unadjusted", + "massflux_up_half", + "du_conv", + "dv_conv", +] + +ignore_dependencies_block3 = [ + "o3p", + "o1d", + "o3", + "nit", + "no", + "no3", + "lumped_n", + "n2o5", + "ho2no2", + "hono2", + "h2o2", + "ch4", + "co", + "hcho", + "meoo", + "meooh", + "h", + "oh", + "ho2", + "cl", + "cl2o2", + "clo", + "oclo", + "br", + "lumped_br", + "brcl", + "brono2", + "n2o", + "lumped_cl", + "hocl", + "hbr", + "hobr", + "clono2", + "cfcl3", + "cf2cl2", + "mebr", + "hono", + "c2h6", + "etoo", + "etooh", + "mecho", + "meco3", + "pan", + "c3h8", + "n_proo", + "i_proo", + "n_prooh", + "i_prooh", + "etcho", + "etco3", + "me2co", + "mecoch2oo", + "mecoch2ooh", + "ppan", + "meono2", + "c5h8", + "iso2", + "isooh", + "ison", + "macr", + "macro2", + "macrooh", + "mpan", + "hacet", + "mgly", + "nald", + "hcooh", + "meco3h", + "meco2h", + "h2", + "meoh", + "msa", + "nh3", + "cs2", + "csul", + "h2s", + "so3", + "passive_o3", + "age_of_air", + "dms", + "so2", + "h2so4", + "dmso", + "monoterpene", + "secondary_organic", + "n_nuc_sol", + "nuc_sol_su", + "nuc_sol_om", + "n_ait_sol", + "ait_sol_su", + "ait_sol_bc", + "ait_sol_om", + "n_acc_sol", + "acc_sol_su", + "acc_sol_bc", + "acc_sol_om", + "acc_sol_ss", + "n_cor_sol", + "cor_sol_su", + "cor_sol_bc", + "cor_sol_om", + "cor_sol_ss", + "n_ait_ins", + "ait_ins_bc", + "ait_ins_om", + "n_acc_ins", + "acc_ins_du", + "n_cor_ins", + "cor_ins_du", + "dmv_conv", + "conv_prog_precip", + "conv_prog_precip", + "dt_conv", + "conv_prog_dtheta", + "dmv_conv", + "conv_prog_dmv", + "dcfl_conv", + "dcff_conv", + "dbcf_conv", + "dt_conv", + "dmv_conv", + "dmcl_conv", + "dms_conv", + "dd_mf_cb", + "cca", + "ccw", + "cv_top", + "cv_base", + "lowest_cv_top", + "lowest_cv_base", + "pres_cv_top", + "pres_cv_base", + "pres_lowest_cv_top", + "pres_lowest_cv_base", + "massflux_up_cmpta", + "dth_conv_noshal", + "dmv_conv_noshal", + "tke_bl", +] diff --git a/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/global.py b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/global.py new file mode 120000 index 000000000..3e96112c8 --- /dev/null +++ b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/global.py @@ -0,0 +1 @@ +../../../../../applications/lfric_atm/optimisation/meto-ex1a/transmute/global.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/kernel b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/kernel new file mode 120000 index 000000000..2a7f97bb3 --- /dev/null +++ b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/kernel @@ -0,0 +1 @@ +../../../../../applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/ \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/science b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/science new file mode 120000 index 000000000..45b5d1f38 --- /dev/null +++ b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/science @@ -0,0 +1 @@ +../../../../../applications/lfric_atm/optimisation/meto-ex1a/transmute/science/ \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/script_options.py b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/script_options.py new file mode 120000 index 000000000..d700f71b8 --- /dev/null +++ b/applications/lfric_atm/optimisation/cpu-azngarch-sandbox/transmute/script_options.py @@ -0,0 +1 @@ +../../../../../applications/lfric_atm/optimisation/meto-ex1a/transmute/script_options.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/global.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/global.py new file mode 120000 index 000000000..9d9260b1e --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/global.py @@ -0,0 +1 @@ +../../meto-ex1a/transmute/global.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/gravity_wave_drag b/applications/lfric_atm/optimisation/esnz-cascade/transmute/gravity_wave_drag new file mode 120000 index 000000000..ed7ee334d --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/gravity_wave_drag @@ -0,0 +1 @@ +../../meto-ex1a/transmute/gravity_wave_drag \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel b/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel new file mode 120000 index 000000000..3190251b7 --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel @@ -0,0 +1 @@ +../../meto-ex1a/transmute/kernel \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/bm_tau_kernel_mod.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/bm_tau_kernel_mod.py deleted file mode 100644 index cc3235be5..000000000 --- a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/bm_tau_kernel_mod.py +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -############################################################################## -""" -Optimisation script that adds OpenMP worksharing-loop directives to speed up -loops before and after a PC2 subroutine call. Some PSyclone dependency errors -need to be overridden; these assignments can be safely parallelised. -""" - -import logging -from psyclone.transformations import TransformationError -from psyclone.psyir.nodes import Loop -from transmute_psytrans.transmute_functions import ( - match_lhs_assignments, - OMP_PARALLEL_LOOP_DO_TRANS_STATIC -) - -# Variables that appear on the left-hand side of assignments -# for which PSyclone dependency errors can be ignored -false_dep_vars = [ - "tau_dec_bm", - "tau_hom_bm", - "tau_mph_bm" -] - - -def trans(psyir): - """ - Apply OpenMP Directives - """ - - # Add parallel do directives to outer loops - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - # Check if any eligible variables appear on the LHS of - # assignment expressions; these lead to false dependency - # errors in the parallel loop transformation that can be - # ignored - ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) - options = {} - if len(ignore_deps_vars) > 0: - options["ignore_dependencies_for"] = ignore_deps_vars - - try: - OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/mphys_kernel_mod.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/mphys_kernel_mod.py deleted file mode 100644 index 41c3d5c95..000000000 --- a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/mphys_kernel_mod.py +++ /dev/null @@ -1,72 +0,0 @@ -############################################################################## -# Copyright (c) 2025, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## -''' -Bespoke Opt script for mphys_kernel_mod to add OpenMP to loops present in -the Kernel. -As PSyclone is detecting a number of lhs rhs dependencies due to the -copies in and out of the kernel, we are needing to provide a list of -ignore_dependencies_for in the transformation options list. -''' - -import logging -from psyclone.transformations import ( - OMPLoopTrans, - TransformationError) -from psyclone.psyir.nodes import Loop - - -omp_transform_par_do = OMPLoopTrans( - omp_schedule="static", - omp_directive="paralleldo") - - -def trans(psyir): - ''' - PSyclone function call, run through psyir object, - each schedule (or subroutine) and apply paralleldo transformations - to each loop in large scale precip. - ''' - - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - options = {"ignore_dependencies_for": [ - "dtheta", # First and Second i, k loop - "dmv_wth", # First and Second i, k loop - "dml_wth", # First and Second i, k loop - "dms_wth", # First and Second i, k loop - "dmr_wth", # Third i, k loop - "dmg_wth", # Forth i, k loop - "murk", # First k, i loop - "dbcf_wth", # Fifth i, k loop - "dcfl_wth", # Fifth i, k loop - "dcff_wth", # Fifth i, k loop - "ls_rain_2d", # Fifth i, k loop - "ls_snow_2d", # Fifth i, k loop - "ls_graup_2d", # Fifth i, k loop - "lsca_2d", # Fifth i, k loop - "ls_rain_3d", # Fifth i, k loop - "ls_snow_3d", # Fifth i, k loop - "precfrac", # Fifth i, k loop - "refl_tot", # Fifth i, k loop - "autoconv", # Fifth i, k loop - "accretion", # Fifth i, k loop - "rim_cry", # Fifth i, k loop - "rim_agg", # Fifth i, k loop - "refl_1km", # Fifth i, k loop - "superc_liq_wth", # Sixth i, k loop - "superc_rain_wth", # Seventh i, k loop - "sfwater", # Eighth i, k loop - "sfwater", # Second k, i loop - "sfrain", # Third k, i loop - "sfsnow", # Fourth k, i loop - ], - "node-type-check": False} - try: - omp_transform_par_do.apply(loop, options) - - except (TransformationError, IndexError) as err: - logging.warning( - "Could not transform because:\n %s", err) diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/pc2_conv_coupling_kernel_mod.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/pc2_conv_coupling_kernel_mod.py deleted file mode 100644 index d7748acfa..000000000 --- a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/pc2_conv_coupling_kernel_mod.py +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -############################################################################## -""" -Optimisation script that adds OpenMP parallel do worksharing-loop directives. -The main loop requires dynamic schedule to improve load balancing between -threads. Some PSyclone dependency errors and a subroutine thread safety -check need to be overridden; these assignments and subroutine call can be -safely parallelised. Multiple arrays need to be declared OpenMP-private. -""" - -import logging -from psyclone.transformations import (OMPLoopTrans, TransformationError) -from psyclone.psyir.nodes import Loop -from transmute_psytrans.transmute_functions import ( - set_pure_subroutines, - match_lhs_assignments, - OMP_PARALLEL_LOOP_DO_TRANS_STATIC -) - -# Variables that appear on the left-hand side of assignments -# for which PSyclone dependency errors can be ignored -false_dep_vars = [ - "dt_conv_wth", - "dmv_conv_wth", - "dmcl_conv_wth", - "dcfl_conv_wth", - "dbcf_conv_wth" -] - -# Arrays that appear on the left-hand side of assignments -# which trigger automatic array privatisation in PSyclone -private_arrays = [ - "p_forcing", - "p_work", - "t_forcing", - "t_work", - "qv_forcing", - "cfl_forcing", - "qv_work", - "qcl_work", - "cfl_work", - "cff_work", - "bcf_work", - "t_incr", - "qv_incr", - "qcl_incr", - "cfl_incr", - "bcf_incr", -] - - -def trans(psyir): - """ - Apply OpenMP Directives - """ - - # Declare subroutine "pc2_hom_conv" as pure to enable parallelisation - # of the encompassing loop - set_pure_subroutines(psyir, "pc2_hom_conv") - - # OMPLoopTrans supports automatic array privatisation - omp_pardo_dyn = OMPLoopTrans(omp_schedule="dynamic", - omp_directive="paralleldo") - - # Add parallel do directives to outer loops - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - # Check if any variables appear on the LHS of assignment - # expressions that require "privatisation" or lead to false - # dependency errors in the parallel loop transformation. - options = {"privatise_arrays": - len(match_lhs_assignments(loop, private_arrays)) > 0} - ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) - if len(ignore_deps_vars) > 0: - options["ignore_dependencies_for"] = ignore_deps_vars - - # The loop with privatised arrays also needs dynamic schedule - if options["privatise_arrays"]: - try: - omp_pardo_dyn.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPLoopTrans failed: %s", err) - else: - try: - OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/pc2_initiation_kernel_mod.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/pc2_initiation_kernel_mod.py deleted file mode 100644 index ed4a0e90e..000000000 --- a/applications/lfric_atm/optimisation/esnz-cascade/transmute/kernel/pc2_initiation_kernel_mod.py +++ /dev/null @@ -1,57 +0,0 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -############################################################################## -""" -Optimisation script that adds OpenMP worksharing-loop directives to speed up -various loops. Some PSyclone dependency errors need to be overridden; these -assignments can be safely parallelised. -""" - -import logging -from psyclone.transformations import TransformationError -from psyclone.psyir.nodes import Loop -from transmute_psytrans.transmute_functions import ( - match_lhs_assignments, - OMP_PARALLEL_LOOP_DO_TRANS_STATIC -) - -# Variables that appear on the left-hand side of assignments -# for which PSyclone dependency errors can be ignored -false_dep_vars = [ - "dtheta_inc_wth", - "dmv_inc_wth", - "dmcl_inc_wth", - "dmci_inc_wth", - "dms_inc_wth", - "dcfl_inc_wth", - "dcff_inc_wth", - "dbcf_inc_wth", - "sskew_bm", - "svar_bm", - "svar_tb" -] - - -def trans(psyir): - """ - Apply OpenMP Directives - """ - - # Add parallel do directives to outer loops - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - # Check if any eligible variables appear on the LHS of - # assignment expressions; these lead to false dependency - # errors in the parallel loop transformation that can be - # ignored - ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) - options = {} - if len(ignore_deps_vars) > 0: - options["ignore_dependencies_for"] = ignore_deps_vars - - try: - OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bl_forced_cu.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bl_forced_cu.py new file mode 100644 index 000000000..b34a512f6 --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bl_forced_cu.py @@ -0,0 +1,47 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to target loops over index i instead of +index j. Trip count of j loops is 1 in LFRic, which prevents parallel +execution. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + get_outer_loops, + get_compiler, + first_priv_red_init, + OMP_PARALLEL_LOOP_DO_TRANS_DYNAMIC, + OMP_PARALLEL_LOOP_DO_TRANS_STATIC +) + + +def trans(psyir): + """ + Apply OpenMP Directives + """ + + # Identify outer loops + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + # Apply OpenMP parallel do directives and use workaround for + # firstprivate variable issue; replicate dynamic and static + # schedules of the original implementation + try: + for idx, loop in enumerate(outer_loops): + if get_compiler() == 'cce': + first_priv_red_init(loop, ["cf_base", "cf_forced", "dcfl", + "dqcl", "qcl_forced", "qcl_tol"]) + if idx == 0: + OMP_PARALLEL_LOOP_DO_TRANS_DYNAMIC.apply(loop.walk(Loop)[1]) + else: + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop.walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bm_initiate.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bm_initiate.py new file mode 100644 index 000000000..b1286eb05 --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bm_initiate.py @@ -0,0 +1,145 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to target loops over index i instead of +index j. Trip count of j loops is 1 in LFRic, which prevents parallel +execution. Private variables need to be declared explicitly as PSyclone +analysis currently misses a scalar variable that a subroutine modifies in +a parallel region. PSyclone thread safety checks need to be overridden; +the subroutines can be safely parallelised. Compiler directives used in +the original code are re-inserted for performance and consistency of output. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import (Loop, CodeBlock) +from transmute_psytrans.transmute_functions import ( + set_pure_subroutines, + get_outer_loops, + mark_explicit_privates, + get_compiler, + first_priv_red_init, + match_lhs_assignments, + match_call_args, + OMP_PARALLEL_REGION_TRANS, + OMP_DO_LOOP_TRANS_STATIC +) + +# Variables in parallel region that need to be private +private_variables = [ + "alphal", "alx", "i", "j", "k", "km1", "kp1", "mux", "tmp", + "frac_init", "kk", "kkm1", "kkp1", "qc", "qc_points", "qsl", + "tlx", "qsi", "idx", "deltacl_c", "deltacf_c", "deltaql_c", + "cf_c", "cfl_c", "cff_c" +] + +# Subroutines that need to be declared as "pure" +pure_subroutines = ["qsat", "qsat_mix", "qsat_wat", "qsat_wat_mix"] + +# Variables that appear on the left-hand side of assignments +# or as call arguments for which PSyclone dependency errors +# can be ignored +false_dep_vars = [ + "qc_points", + "idx", + "tl_in", + "p_theta_levels", + "qsi_lay", + "qsl_lay", +] + + +class CompilerDirective(): + """ + Custom compiler directive class to avoid an issue + with fparser.two.Fortran2003.Directive that will + be resolved in an upcoming fparser release. + """ + def __init__(self, directive): + self.directive = directive + + def tofortran(self): + """ + Return directive with prefix + """ + return "!DIR$ " + self.directive + + +def trans(psyir): + """ + Apply OpenMP and Compiler Directives + """ + + # Declare subroutines as pure to enable parallelisation + # of the encompassing loops + set_pure_subroutines(psyir, pure_subroutines) + + # Identify outer loops for setting up parallel regions + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + # Check if first OpenMP region can be parallelised and + # apply directives + try: + OMP_PARALLEL_REGION_TRANS.validate(outer_loops[0:2]) + OMP_PARALLEL_REGION_TRANS.apply(outer_loops[0:2]) + OMP_DO_LOOP_TRANS_STATIC.apply(outer_loops[0]) + OMP_DO_LOOP_TRANS_STATIC.apply(outer_loops[1].walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("Parallelisation of the 1st region failed: %s", err) + + # Declare private symbols for the last loop nest explicitly, + # PSyclone misses one + mark_explicit_privates(outer_loops[2], private_variables) + + # Parallelise the second region and insert compiler directives + # Add redundant variable initialisation to work around a known + # PSyclone issue when using CCE + try: + if get_compiler() == 'cce': + first_priv_red_init(outer_loops[2], ["i", "j", "k"]) + + OMP_PARALLEL_REGION_TRANS.validate(outer_loops[2:3]) + OMP_PARALLEL_REGION_TRANS.apply(outer_loops[2]) + + # Insert before OpenMP directives to avoid PSyclone errors + if get_compiler() == "cce": + for loop in outer_loops[2].walk(Loop)[3:5]: + cblock = CodeBlock([CompilerDirective("NOFISSION")], + CodeBlock.Structure.STATEMENT) + insert_at = loop.parent.children.index(loop) + loop.parent.children.insert(insert_at, cblock) + + for loop in outer_loops[2].walk(Loop)[13:16]: + cblock = CodeBlock([CompilerDirective("IVDEP")], + CodeBlock.Structure.STATEMENT) + insert_at = loop.parent.children.index(loop) + loop.parent.children.insert(insert_at, cblock) + + for loop in outer_loops[2].walk(Loop)[2:7]: + # Check if any eligible variables appear in subroutine + # call arguments; these lead to false dependency errors + # in the parallel loop transformation that can be + # ignored + ignore_deps_vars = match_call_args(loop, false_dep_vars) + options = {} + if len(ignore_deps_vars) > 0: + options["ignore_dependencies_for"] = ignore_deps_vars + OMP_DO_LOOP_TRANS_STATIC.apply(loop, options) + + for loop in outer_loops[2].walk(Loop)[8:13:2]: + # Check if any eligible variables appear on the LHS of + # assignment expressions to ignore false dependency errors + ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) + options = {} + if len(ignore_deps_vars) > 0: + options["ignore_dependencies_for"] = ignore_deps_vars + + OMP_DO_LOOP_TRANS_STATIC.apply(loop, options) + + except (TransformationError, IndexError) as err: + logging.warning("Parallelisation of the 2nd region failed: %s", err) diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_initiation_ctl.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_initiation_ctl.py new file mode 100644 index 000000000..f0d19a243 --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_initiation_ctl.py @@ -0,0 +1,37 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to parallelise additional loops. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + get_outer_loops, + OMP_PARALLEL_LOOP_DO_TRANS_STATIC, +) + + +def trans(psyir): + """ + Apply OpenMP Directives + """ + + # Identify outer loops in the subroutine + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + try: + # Parallelise k-loops and i-loops (j-loops have a trip count of 1) + for loop in outer_loops: + if loop.variable.name == 'k': + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop) + elif loop.variable.name == 'j': + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop.walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/science b/applications/lfric_atm/optimisation/esnz-cascade/transmute/science new file mode 120000 index 000000000..aa26e0e14 --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/science @@ -0,0 +1 @@ +../../meto-ex1a/transmute/science \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/esnz-cascade/transmute/script_options.py b/applications/lfric_atm/optimisation/esnz-cascade/transmute/script_options.py new file mode 120000 index 000000000..d887dbe9e --- /dev/null +++ b/applications/lfric_atm/optimisation/esnz-cascade/transmute/script_options.py @@ -0,0 +1 @@ +../../meto-ex1a/transmute/script_options.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/conv_gr_alg_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/conv_gr_alg_mod.py new file mode 100644 index 000000000..ab4456871 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/conv_gr_alg_mod.py @@ -0,0 +1,30 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +""" +PSyclone transformation script for the LFRic (Dynamo0p3) API to apply +colouring and redundant computation to the level-1 halo for +the initialisation built-ins generically. + +""" + +from psyclone_tools import ( + redundant_computation_setval, + colour_loops, + view_transformed_schedule, +) + + +def trans(psyir): + """ + Applies PSyclone colouring and redundant computation transformations. + + :param psyir: the PSyIR of the PSy-layer. + :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` + + """ + redundant_computation_setval(psyir) + colour_loops(psyir) + view_transformed_schedule(psyir) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/runtime_constants/physics_constants_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/runtime_constants/physics_constants_mod.py new file mode 100644 index 000000000..827b59572 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/runtime_constants/physics_constants_mod.py @@ -0,0 +1,229 @@ +############################################################################## +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + + +'''PSyclone transformation script for physics_constants_mod to apply colouring +and GPU offloading/CPU parallelization. Also adds redundant computation to +the level-1 halo for setval_* generically. This is based on +https://github.com/stfc/PSyclone/blob/master/examples/lfric/ +scripts/gpu_offloading.py . + +''' + +import os +import sys +from psyclone.domain.lfric import LFRicConstants +from psyclone.psyir.nodes import Directive, Loop, Routine +from psyclone.psyir.transformations import ( + ACCKernelsTrans, TransformationError, OMPTargetTrans, + OMPDeclareTargetTrans) +from psyclone.transformations import ( + Dynamo0p3ColourTrans, Dynamo0p3OMPLoopTrans, + Dynamo0p3RedundantComputationTrans, OMPParallelTrans, + ACCParallelTrans, ACCLoopTrans, ACCRoutineTrans, + OMPLoopTrans) +from psyclone.domain.common.transformations import KernelModuleInlineTrans + + +# Names of any invoke that we won't add any GPU offloading +INVOKE_EXCLUSIONS = [ +] + +# Names of any kernel that we won't add parallelization +KERNEL_EXCLUSIONS = ["get_Pnm_star_code",] +# get_Pnm_star_code has data dependencies in the loops +# and is tested to be not suitable +# for parallelization + +# Names of any kernels that we won't offload to GPU +GPU_KERNEL_EXCLUSIONS = [ +] + +OFFLOAD_DIRECTIVES = os.getenv('LFRIC_OFFLOAD_DIRECTIVES', "none") + + +def trans(psyir): + '''Applies PSyclone colouring and GPU offloading transformations. Any + kernels that cannot be offloaded to GPU are parallelised using OpenMP + on the CPU if they can be parallelised. Any setval_* kernels are + transformed so as to compute into the L1 halos. + + :param psyir: the PSyIR of the PSy-layer. + :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` + + ''' + inline_trans = KernelModuleInlineTrans() + rtrans = Dynamo0p3RedundantComputationTrans() + ctrans = Dynamo0p3ColourTrans() + otrans = Dynamo0p3OMPLoopTrans() + const = LFRicConstants() + cpu_parallel = OMPParallelTrans() + + if OFFLOAD_DIRECTIVES == "omp": + # Use OpenMP offloading + loop_offloading_trans = OMPLoopTrans( + omp_directive="teamsdistributeparalleldo", + omp_schedule="none" + ) + # OpenMP does not have a kernels parallelism directive equivalent + # to OpenACC 'kernels' + kernels_trans = None + gpu_region_trans = OMPTargetTrans() + gpu_annotation_trans = OMPDeclareTargetTrans() + elif OFFLOAD_DIRECTIVES == "acc": + # Use OpenACC offloading + loop_offloading_trans = ACCLoopTrans() + kernels_trans = ACCKernelsTrans() + gpu_region_trans = ACCParallelTrans(default_present=False) + gpu_annotation_trans = ACCRoutineTrans() + elif OFFLOAD_DIRECTIVES == "none": + pass + else: + print( + f"The PSyclone transformation script expects the " + f"LFRIC_OFFLOAD_DIRECTIVES to be set to 'omp' or 'acc' or " + f"'none' but found '{OFFLOAD_DIRECTIVES}'." + ) + sys.exit(-1) + + print(f"PSy name = '{psyir.name}'") + + for subroutine in psyir.walk(Routine): + + print("Transforming invoke '{0}' ...".format(subroutine.name)) + + # Make setval_* compute redundantly to the level 1 halo if it + # is in its own loop + for loop in subroutine.loops(): + if loop.iteration_space == "dof": + if len(loop.kernels()) == 1: + if loop.kernels()[0].name in ["setval_c"]: + rtrans.apply(loop, options={"depth": 1}) + + if ( + psyir.name.lower() in INVOKE_EXCLUSIONS + or OFFLOAD_DIRECTIVES == "none" + ): + print( + f"Not adding GPU offloading to invoke '{subroutine.name}'" + ) + offload = False + else: + offload = True + + # Keep a record of any kernels we fail and succeed to offload + succeeded_offload = set() + failed_to_offload = set() + + # Colour loops over cells unless they are on discontinuous spaces + # (alternatively we could annotate the kernels with atomics) + for loop in subroutine.loops(): + if loop.iteration_space.endswith("cell_column"): + if (loop.field_space.orig_name not in + const.VALID_DISCONTINUOUS_NAMES): + ctrans.apply(loop) + + # Mark kernels inside the loops over cells as GPU-enabled + # and inline them. + for loop in subroutine.loops(): + if loop.iteration_space.endswith("cell_column"): + if offload: + for kern in loop.kernels(): + if kern.name.lower() in ( + GPU_KERNEL_EXCLUSIONS + KERNEL_EXCLUSIONS + + list(succeeded_offload) + ): + continue + + try: + gpu_annotation_trans.apply( + kern, options={'force': True} + ) + print(f"GPU-annotated kernel '{kern.name}'") + + try: + inline_trans.apply(kern) + print(f"Module-inlined kernel '{kern.name}'") + succeeded_offload.add(kern.name.lower()) + except TransformationError as err: + print( + f"Failed to module-inline '{kern.name}'" + f" due to:\n{err.value}" + ) + except TransformationError as err: + failed_to_offload.add(kern.name.lower()) + print( + f"Failed to annotate '{kern.name}' with " + f"GPU-enabled directive due to:\n{err.value}" + ) + # For annotated or inlined kernels we could attempt to + # provide compile-time dimensions for the temporary + # arrays and convert to code unsupported intrinsics. + + # Add GPU offloading to loops unless they are over colours or are null. + for loop in subroutine.walk(Loop): + kernel_names = [k.name.lower() for k in loop.kernels()] + if offload and all( + name not in ( + list(failed_to_offload) + GPU_KERNEL_EXCLUSIONS + + KERNEL_EXCLUSIONS + ) + for name in kernel_names + ): + try: + if loop.loop_type == "colours": + pass + if loop.loop_type == "colour": + loop_offloading_trans.apply( + loop, options={"independent": True}) + gpu_region_trans.apply(loop.ancestor(Directive)) + if loop.loop_type == "": + loop_offloading_trans.apply( + loop, options={"independent": True} + ) + gpu_region_trans.apply(loop.ancestor(Directive)) + if loop.loop_type == "dof": + # Loops over dofs can contains reductions + if kernels_trans: + # If kernel offloading is available it should + # manage them + kernels_trans.apply(loop) + else: + # Otherwise, if the reductions exists, they will + # be detected by the dependencyAnalysis and raise + # a TransformationError captured below + loop_offloading_trans.apply( + loop, options={"independent": True}) + gpu_region_trans.apply(loop.ancestor(Directive)) + # Alternatively we could use loop parallelism with + # reduction clauses + print(f"Successfully offloaded loop with {kernel_names}") + except TransformationError as err: + print(f"Failed to offload loop with {kernel_names} " + f"because: {err}") + + # Apply OpenMP thread parallelism for any kernels we've not been able + # to offload to GPU. + for loop in subroutine.walk(Loop): + if any( + kern.name.lower() in KERNEL_EXCLUSIONS + for kern in loop.kernels() + ): + continue + + if ( + not offload + or any( + kern.name.lower() in ( + list(failed_to_offload) + GPU_KERNEL_EXCLUSIONS + ) + for kern in loop.kernels() + ) + ): + if loop.loop_type not in ["colours", "null"]: + cpu_parallel.apply(loop) + otrans.apply(loop, options={"reprod": True}) + print(subroutine.view()) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/skeb_main_alg_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/skeb_main_alg_mod.py new file mode 100644 index 000000000..1553a56d3 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/skeb_main_alg_mod.py @@ -0,0 +1,239 @@ +############################################################################## +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + + +'''PSyclone transformation script for skeb_main_alg_mod.py to apply colouring +and GPU offloading/CPU parallelization. Also adds redundant computation to the +level-1 halo for setval_* generically. This is based on +https://github.com/stfc/PSyclone/blob/master/examples/lfric/ +scripts/gpu_offloading.py . + +''' + +import os +import sys +from psyclone.domain.lfric import LFRicConstants +from psyclone.psyir.nodes import Directive, Loop, Routine +from psyclone.psyir.transformations import ( + ACCKernelsTrans, TransformationError, OMPTargetTrans, + OMPDeclareTargetTrans) +from psyclone.transformations import ( + Dynamo0p3ColourTrans, Dynamo0p3OMPLoopTrans, + Dynamo0p3RedundantComputationTrans, OMPParallelTrans, + ACCParallelTrans, ACCLoopTrans, ACCRoutineTrans, + OMPLoopTrans) +from psyclone.domain.common.transformations import KernelModuleInlineTrans + + +# Names of any invoke that we won't add any GPU offloading +INVOKE_EXCLUSIONS = [ +] + +# Names of any kernel that we won't add parallelization +KERNEL_EXCLUSIONS = [ +] + +# Names of any kernels that we won't offload to GPU +GPU_KERNEL_EXCLUSIONS = [ +] + +OFFLOAD_DIRECTIVES = os.getenv('LFRIC_OFFLOAD_DIRECTIVES', "none") + + +def trans(psyir): + '''Applies PSyclone colouring and GPU offloading transformations. Any + kernels that cannot be offloaded to GPU are parallelised using OpenMP + on the CPU if they can be parallelised. Any setval_* kernels are + transformed so as to compute into the L1 halos. + + :param psyir: the PSyIR of the PSy-layer. + :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` + + ''' + inline_trans = KernelModuleInlineTrans() + rtrans = Dynamo0p3RedundantComputationTrans() + ctrans = Dynamo0p3ColourTrans() + otrans = Dynamo0p3OMPLoopTrans() + const = LFRicConstants() + cpu_parallel = OMPParallelTrans() + + if OFFLOAD_DIRECTIVES == "omp": + # Use OpenMP offloading + loop_offloading_trans = OMPLoopTrans( + omp_directive="teamsdistributeparalleldo", + omp_schedule="none" + ) + # OpenMP does not have a kernels parallelism directive equivalent + # to OpenACC 'kernels' + kernels_trans = None + gpu_region_trans = OMPTargetTrans() + gpu_annotation_trans = OMPDeclareTargetTrans() + elif OFFLOAD_DIRECTIVES == "acc": + # Use OpenACC offloading + loop_offloading_trans = ACCLoopTrans() + kernels_trans = ACCKernelsTrans() + gpu_region_trans = ACCParallelTrans(default_present=False) + gpu_annotation_trans = ACCRoutineTrans() + elif OFFLOAD_DIRECTIVES == "none": + pass + else: + print( + f"The PSyclone transformation script expects the " + f"LFRIC_OFFLOAD_DIRECTIVES to be set to 'omp' or 'acc' or " + f"'none' but found '{OFFLOAD_DIRECTIVES}'." + ) + sys.exit(-1) + + print(f"PSy name = '{psyir.name}'") + + for subroutine in psyir.walk(Routine): + + print("Transforming invoke '{0}' ...".format(subroutine.name)) + + # Make setval_* compute redundantly to the level 1 halo if it + # is in its own loop + for loop in subroutine.loops(): + if loop.iteration_space == "dof": + if len(loop.kernels()) == 1: + if loop.kernels()[0].name in ["setval_c"]: + rtrans.apply(loop, options={"depth": 1}) + + if ( + psyir.name.lower() in INVOKE_EXCLUSIONS + or OFFLOAD_DIRECTIVES == "none" + ): + print( + f"Not adding GPU offloading to invoke '{subroutine.name}'" + ) + offload = False + else: + offload = True + + # Keep a record of any kernels we fail and succeed to offload + succeeded_offload = set() + failed_to_offload = set() + + # Colour loops over cells unless they are on discontinuous spaces + # (alternatively we could annotate the kernels with atomics) + for loop in subroutine.loops(): + if loop.iteration_space.endswith("cell_column"): + if (loop.field_space.orig_name not in + const.VALID_DISCONTINUOUS_NAMES): + ctrans.apply(loop) + + # Mark kernels inside the loops over cells as GPU-enabled + # and inline them. + for loop in subroutine.loops(): + if loop.iteration_space.endswith("cell_column"): + if offload: + for kern in loop.kernels(): + if kern.name.lower() in ( + GPU_KERNEL_EXCLUSIONS + KERNEL_EXCLUSIONS + + list(succeeded_offload) + ): + continue + + try: + gpu_annotation_trans.apply( + kern, options={'force': True} + ) + print(f"GPU-annotated kernel '{kern.name}'") + + try: + inline_trans.apply(kern) + print(f"Module-inlined kernel '{kern.name}'") + succeeded_offload.add(kern.name.lower()) + except TransformationError as err: + print( + f"Failed to module-inline '{kern.name}'" + f" due to:\n{err.value}" + ) + except TransformationError as err: + failed_to_offload.add(kern.name.lower()) + print( + f"Failed to annotate '{kern.name}' with " + f"GPU-enabled directive due to:\n{err.value}" + ) + # For annotated or inlined kernels we could attempt to + # provide compile-time dimensions for the temporary + # arrays and convert to code unsupported intrinsics. + + # Add GPU offloading to loops unless they are over colours or are null. + for loop in subroutine.walk(Loop): + kernel_names = [ + k.name.lower() for k in loop.kernels() + ] + if offload and all( + name not in ( + list(failed_to_offload) + GPU_KERNEL_EXCLUSIONS + + KERNEL_EXCLUSIONS + ) + for name in kernel_names + ): + try: + if loop.loop_type == "colours": + pass + + if loop.loop_type == "colour": + loop_offloading_trans.apply( + loop, options={"independent": True} + ) + gpu_region_trans.apply(loop.ancestor(Directive)) + + if loop.loop_type == "": + loop_offloading_trans.apply( + loop, options={"independent": True} + ) + gpu_region_trans.apply(loop.ancestor(Directive)) + + if loop.loop_type == "dof": + # Loops over dofs can contains reductions + if kernels_trans: + # If kernel offloading is available it should + # manage them + kernels_trans.apply(loop) + else: + # Otherwise, if the reductions exists, they + # will be detected by the dependencyAnalysis + # and raise a TransformationError captured + # below + loop_offloading_trans.apply( + loop, options={"independent": True} + ) + gpu_region_trans.apply(loop.ancestor(Directive)) + + # Alternatively we could use loop parallelism with + # reduction clauses + print(f"Successfully offloaded loop with {kernel_names}") + except TransformationError as err: + print( + f"Failed to offload loop with {kernel_names} " + f"because: {err}" + ) + + # Apply OpenMP thread parallelism for any kernels we've not been able + # to offload to GPU. + for loop in subroutine.walk(Loop): + if any( + kern.name.lower() in KERNEL_EXCLUSIONS + for kern in loop.kernels() + ): + continue + + if ( + not offload + or any( + kern.name.lower() in ( + list(failed_to_offload) + GPU_KERNEL_EXCLUSIONS + ) + for kern in loop.kernels() + ) + ): + if loop.loop_type not in ["colours", "null"]: + cpu_parallel.apply(loop) + otrans.apply(loop, options={"reprod": True}) + + print(subroutine.view()) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/spt_main_alg_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/spt_main_alg_mod.py new file mode 100644 index 000000000..e8d1d7bfd --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/psykal/algorithm/spt_main_alg_mod.py @@ -0,0 +1,234 @@ +############################################################################## +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + + +'''PSyclone transformation script for spt_main_alg_mod to apply colouring +and GPU offloading/CPU parallelization. Also adds redundant computation to +the level-1 halo for setval_* generically. This is based on +https://github.com/stfc/PSyclone/blob/master/examples/lfric/ +scripts/gpu_offloading.py . + +''' + +import os +import sys +from psyclone.domain.lfric import LFRicConstants +from psyclone.psyir.nodes import Directive, Loop, Routine +from psyclone.psyir.transformations import ( + ACCKernelsTrans, TransformationError, OMPTargetTrans, + OMPDeclareTargetTrans) +from psyclone.transformations import ( + Dynamo0p3ColourTrans, Dynamo0p3OMPLoopTrans, + Dynamo0p3RedundantComputationTrans, OMPParallelTrans, + ACCParallelTrans, ACCLoopTrans, ACCRoutineTrans, + OMPLoopTrans) +from psyclone.domain.common.transformations import KernelModuleInlineTrans + + +# Names of any invoke that we won't add any GPU offloading +INVOKE_EXCLUSIONS = [ +] + +# Names of any kernel that we won't add parallelization +KERNEL_EXCLUSIONS = [ +] + +# Names of any kernels that we won't offload to GPU +GPU_KERNEL_EXCLUSIONS = ["spt_saturation_cap_code",] +# spt_saturation_cap_code: GPU transformation cannot be applied because of +# using qsat_wat_mix from qsat_mod. As qsat_mod is going to be modified in +# future, this falls out of the scope of the NGARCH project. +# Error message: Transformation Error: Kernel 'spt_saturation_cap_code' +# accesses the symbol 'qsat_wat_mix: RoutineSymbol' which is imported. +# If this symbol represents data then it must first be converted to a +# Kernel argument using the KernelImportsToArguments transformation. + +OFFLOAD_DIRECTIVES = os.getenv('LFRIC_OFFLOAD_DIRECTIVES', "none") + + +def trans(psyir): + '''Applies PSyclone colouring and GPU offloading transformations. Any + kernels that cannot be offloaded to GPU are parallelised using OpenMP + on the CPU if they can be parallelised. Any setval_* kernels are + transformed so as to compute into the L1 halos. + + :param psyir: the PSyIR of the PSy-layer. + :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` + + ''' + inline_trans = KernelModuleInlineTrans() + rtrans = Dynamo0p3RedundantComputationTrans() + ctrans = Dynamo0p3ColourTrans() + otrans = Dynamo0p3OMPLoopTrans() + const = LFRicConstants() + cpu_parallel = OMPParallelTrans() + + if OFFLOAD_DIRECTIVES == "omp": + # Use OpenMP offloading + loop_offloading_trans = OMPLoopTrans( + omp_directive="teamsdistributeparalleldo", + omp_schedule="none" + ) + # OpenMP does not have a kernels parallelism directive equivalent + # to OpenACC 'kernels' + kernels_trans = None + gpu_region_trans = OMPTargetTrans() + gpu_annotation_trans = OMPDeclareTargetTrans() + elif OFFLOAD_DIRECTIVES == "acc": + # Use OpenACC offloading + loop_offloading_trans = ACCLoopTrans() + kernels_trans = ACCKernelsTrans() + gpu_region_trans = ACCParallelTrans(default_present=False) + gpu_annotation_trans = ACCRoutineTrans() + elif OFFLOAD_DIRECTIVES == "none": + pass + else: + print( + f"The PSyclone transformation script expects the " + f"LFRIC_OFFLOAD_DIRECTIVES to be set to 'omp' or 'acc' or " + f"'none' but found '{OFFLOAD_DIRECTIVES}'." + ) + sys.exit(-1) + + print(f"PSy name = '{psyir.name}'") + + for subroutine in psyir.walk(Routine): + + print("Transforming invoke '{0}' ...".format(subroutine.name)) + + # Make setval_* compute redundantly to the level 1 halo if it + # is in its own loop + for loop in subroutine.loops(): + if loop.iteration_space == "dof": + if len(loop.kernels()) == 1: + if loop.kernels()[0].name in ["setval_c"]: + rtrans.apply(loop, options={"depth": 1}) + + if ( + psyir.name.lower() in INVOKE_EXCLUSIONS + or OFFLOAD_DIRECTIVES == "none" + ): + print( + f"Not adding GPU offloading to invoke '{subroutine.name}'" + ) + offload = False + else: + offload = True + + # Keep a record of any kernels we fail and succeed to offload + succeeded_offload = set() + failed_to_offload = set() + + # Colour loops over cells unless they are on discontinuous spaces + # (alternatively we could annotate the kernels with atomics) + for loop in subroutine.loops(): + if loop.iteration_space.endswith("cell_column"): + if (loop.field_space.orig_name not in + const.VALID_DISCONTINUOUS_NAMES): + ctrans.apply(loop) + + # Mark kernels inside the loops over cells as GPU-enabled + # and inline them. + for loop in subroutine.loops(): + if loop.iteration_space.endswith("cell_column"): + if offload: + for kern in loop.kernels(): + if kern.name.lower() in ( + GPU_KERNEL_EXCLUSIONS + KERNEL_EXCLUSIONS + + list(succeeded_offload) + ): + continue + + try: + gpu_annotation_trans.apply( + kern, options={'force': True} + ) + print(f"GPU-annotated kernel '{kern.name}'") + + try: + inline_trans.apply(kern) + print(f"Module-inlined kernel '{kern.name}'") + succeeded_offload.add(kern.name.lower()) + except TransformationError as err: + print( + f"Failed to module-inline '{kern.name}'" + f" due to:\n{err.value}" + ) + except TransformationError as err: + failed_to_offload.add(kern.name.lower()) + print( + f"Failed to annotate '{kern.name}' with " + f"GPU-enabled directive due to:\n{err.value}" + ) + # For annotated or inlined kernels we could attempt to + # provide compile-time dimensions for the temporary + # arrays and convert to code unsupported intrinsics. + + # Add GPU offloading to loops unless they are over colours or are null. + for loop in subroutine.walk(Loop): + kernel_names = [k.name.lower() for k in loop.kernels()] + if offload and all( + name not in ( + list(failed_to_offload) + GPU_KERNEL_EXCLUSIONS + + KERNEL_EXCLUSIONS + ) + for name in kernel_names + ): + try: + if loop.loop_type == "colours": + pass + if loop.loop_type == "colour": + loop_offloading_trans.apply( + loop, options={"independent": True}) + gpu_region_trans.apply(loop.ancestor(Directive)) + if loop.loop_type == "": + loop_offloading_trans.apply( + loop, options={"independent": True}) + gpu_region_trans.apply(loop.ancestor(Directive)) + if loop.loop_type == "dof": + # Loops over dofs can contains reductions + if kernels_trans: + # If kernel offloading is available it should + # manage them + kernels_trans.apply(loop) + else: + # Otherwise, if the reductions exists, they will + # be detected by the dependencyAnalysis and raise + # a TransformationError captured below + loop_offloading_trans.apply( + loop, options={"independent": True}) + gpu_region_trans.apply(loop.ancestor(Directive)) + # Alternatively we could use loop parallelism with + # reduction clauses + print(f"Successfully offloaded loop with {kernel_names}") + except TransformationError as err: + print(f"Failed to offload loop with {kernel_names} " + f"because: {err}") + + # Apply OpenMP thread parallelism for any kernels we've not been able + # to offload to GPU. + for loop in subroutine.walk(Loop): + if any( + kern.name.lower() in KERNEL_EXCLUSIONS + for kern in loop.kernels() + ): + continue + + if ( + not offload + or any( + kern.name.lower() in ( + list(failed_to_offload) + GPU_KERNEL_EXCLUSIONS + ) + for kern in loop.kernels() + ) + ): + if loop.loop_type not in ["colours", "null"]: + cpu_parallel.apply(loop) + otrans.apply(loop, options={"reprod": True}) + + print(subroutine.view()) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/bl_diags_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/bl_diags_mod.py new file mode 100644 index 000000000..2fa660bdc --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/bl_diags_mod.py @@ -0,0 +1,33 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +''' +Bespoke Opt script for bl_diags_mod to add OpenMP to loops present in +the file. - To be replaced by a global in #900 +''' + +import logging +from psyclone.transformations import ( + TransformationError) +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + OMP_PARALLEL_LOOP_DO_TRANS_STATIC, +) + + +def trans(psyir): + ''' + Work through each loop in bl_diags_mod and add a parallel region + ''' + for loop in psyir.walk(Loop): + if not loop.ancestor(Loop): + options = { + "node-type-check": False} + try: + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) + + except (TransformationError, IndexError) as err: + logging.warning( + "Could not transform because:\n %s", err) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/kmkhz_9c_wtrac.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/kmkhz_9c_wtrac.py new file mode 100644 index 000000000..4f08b7b3c --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/kmkhz_9c_wtrac.py @@ -0,0 +1,80 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +''' +Bespoke script for kmkhz_9c_wtrac. +Remove any j loops. +Place a OMP parallel do inside the i_wt loop. +''' + +import logging +from psyclone.psyir.nodes import ( + Schedule, + Routine, + Loop, + OMPParallelDirective, +) +from psyclone.transformations import TransformationError +from transmute_psytrans.transmute_functions import ( + loop_replacement_of, + get_compiler, + first_priv_red_init, + OMP_PARALLEL_LOOP_DO_TRANS_STATIC, +) + +Loop.set_loop_type_inference_rules({ + "i_wt": {"variable": "i_wt"}, + "j": {"variable": "j"}}) + + +def trans(psyir): + """ + Bespoke script for kmkhz_9c_wtrac + """ + + # For the PSyclone 3.1 bug with CCE. Certain files + # are causing a first private to be generated in the parallel section. + first_private_list = [ + "dz_disc", + "qw_lapse", + "k", + "fa_tend", + "inv_tend", + "ml_tend", + "totqf_efl" + ] + + # Remove any loops relating to j loop type + for node in psyir.walk(Routine): + loop_replacement_of(node, "j") + + # Span a parallel section across the whole routine, + # apart for a few exceptions provided + for loop in psyir.walk(Loop): + loop_ancestor_type = "" + try: + loop_ancestor_type = loop.ancestor(Loop).loop_type + # pylint: disable=bare-except + except: # noqa: E722 + pass + if loop_ancestor_type: + if loop_ancestor_type == "i_wt": + # Span the region + try: + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply( + loop) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelLoopTrans failed: %s", err) + + # CCE first private issue with 3.1, to be removed longer term + # pylint: disable=too-many-nested-blocks + if get_compiler() == "cce": + for routine in psyir.walk(Routine): + for node in routine.children: + for schedule in node.walk(Schedule): + for child in schedule.children: + if isinstance(child, OMPParallelDirective): + first_priv_red_init(child, first_private_list) + break diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/local.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/local.py new file mode 100644 index 000000000..edbef2b99 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/local.py @@ -0,0 +1,176 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +''' +Local script for Boundary layer. +This by default removes the j loop(s) and replaces it with a init, +spans a PARALLEL region across the whole file, +and then adds OMP DO to the top most loop in each group of loops. +There are some small bespoke needs for the 6x files that this currently +affects which are captured below as they are initialised. + +This is currently used by the following files: +* bl_lsp +* btq_int +* ex_flux_tq +* ex_flux_uv +* kmkh +* tr_mix +* imp_mix +* fm_drag +''' + +import logging +from psyclone.psyir.nodes import ( + Routine, + Loop, + OMPParallelDirective, +) +from psyclone.transformations import (TransformationError) +from transmute_psytrans.transmute_functions import ( + loop_replacement_of, + get_compiler, + first_priv_red_init, + remove_unspanable_nodes, + set_pure_subroutines, + replace_n_threads, + OMP_PARALLEL_REGION_TRANS, + OMP_DO_LOOP_TRANS_STATIC, +) +from boundary_layer.script_options import ( + SCRIPT_OPTIONS_DICT +) + + +Loop.set_loop_type_inference_rules({ + "i_wt": {"variable": "i_wt"}, # For ex_flux_tq.F90 + "ient": {"variable": "ient"}, # For tr_mix.F90 + "ii": {"variable": "ii"}, # For bdy_impl3.F90 + "k": {"variable": "k"}, # For all files which use script + "j": {"variable": "j"}, # For all files which use script + "i": {"variable": "i"}}) # For bdy_impl3.F90 + + +# Longer term we will raise some of these into a override import, see Apps#900 +# pylint: disable=too-many-locals +# pylint: disable=too-many-statements +# pylint: disable=too-many-branches +def trans(psyir): + """ + Local.py script for boundary layer. + This spans a PARALLEL section across the whole file, + and then adds OMP to either to top loop of a nest, or k + + This is currently used by the following files: + * bl_lsp + * btq_int + * ex_flux_tq + * ex_flux_uv + * kmkh + * tr_mix + * imp_mix + * fm_drag + """ + + # options list for Transformation. + options = {} + # First privates created by CCE redundant inits. + first_private_list = [] + # Designate calls in regions as safe to parallelise over. + safe_pure_calls = [] + # Do we update the max_threads variable with a library call? + max_threads_parse = False + # Assignment nodes that we do not wish to parallelise over at the start + loop_type_init = ["j"] + + # Lifted and extended from Global.py + # Given the file, update the above lists with extra options + + # Get the file name to use with the SCRIPT_OPTIONS_DICT + fortran_file_name = str(psyir.root.name) + # Check if file is in the script_options_dict + # Copy out anything that's needed + # Only the options list is currently + if fortran_file_name in SCRIPT_OPTIONS_DICT: + file_overrides = SCRIPT_OPTIONS_DICT[fortran_file_name] + # Update the respective lists if the filename override exists + if "options" in file_overrides.keys(): + options = file_overrides["options"] + if "first_private_list" in file_overrides.keys(): + first_private_list = file_overrides["first_private_list"] + if "safe_pure_calls" in file_overrides.keys(): + safe_pure_calls = file_overrides["safe_pure_calls"] + if "max_threads_parse" in file_overrides.keys(): + max_threads_parse = file_overrides["max_threads_parse"] + if "loop_type_init" in file_overrides.keys(): + for name in file_overrides["loop_type_init"]: + loop_type_init.append(name) + + # Set up some specifics to this local script + + # Remove any j loops and add an init for j + remove_loop_type = ["j"] + # Avoid any nodes related to the timers + timer_routine_names = ["lhook"] + + # Set the pure calls if needed + if safe_pure_calls: + set_pure_subroutines(psyir, safe_pure_calls) + + # Replace max_threads = 1 + if max_threads_parse: + replace_n_threads(psyir, "max_threads") + + # Remove any loops relating to specified loop type + for node in psyir.walk(Routine): + for removal_type in remove_loop_type: + loop_replacement_of(node, removal_type) + + # Span a parallel section across the whole routine, + # apart for a few exceptions provided + for routine in psyir.walk(Routine): + routine_children = remove_unspanable_nodes( + routine, + timer_routine_names, + loop_type_init + ) + # Span the region across filtered down node list + try: + OMP_PARALLEL_REGION_TRANS.apply( + routine_children) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelTrans failed: %s", err) + + # CCE first private issue with 3.1, to be removed longer term + if get_compiler() == "cce" and first_private_list: + for routine in psyir.walk(Routine): + for node in routine.children: + if isinstance(node, OMPParallelDirective): + first_priv_red_init(node, first_private_list) + break + + # Loop ancestor type that a loop cannot have. + avoid_loop_ancestor = ["ii", "k", "i"] + # A loop type which a loop cannot have an OMP do section + avoid_loop_type = ["i_wt", "ient"] + # Work through the loops now in the spanned section and try transformations + for loop in psyir.walk(Loop): + loop_ancestor_type = "" + try: + loop_ancestor_type = loop.ancestor(Loop).loop_type + # pylint: disable=bare-except + except: # noqa: E722 + pass + # Default is there is no Loop ancestor + if (((not loop.ancestor(Loop)) or + # Or the rest, the loop ancestor is not to be avoided + loop_ancestor_type not in avoid_loop_ancestor) and + # And the loop is not of certain loop types + str(loop.loop_type) not in avoid_loop_type): + try: + OMP_DO_LOOP_TRANS_STATIC.apply( + loop, options) + except (TransformationError, IndexError) as err: + logging.warning("OMPLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/script_options.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/script_options.py new file mode 100644 index 000000000..9b27403d1 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/boundary_layer/script_options.py @@ -0,0 +1,165 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +''' +Lift options list and similar from each individual script up into this file. +Aim is to allow the creation of a simple global.py which adds OMP over all +loops. The option which matches the file being worked on can be pulled in +and referenced. This helps reduce the number of files needed. + +The following files have overrides below: +* bl_lsp +* btq_int +* ex_flux_tq +* ex_flux_uv +* kmkh +* tr_mix +* imp_mix +* fm_drag +''' + +FILE_EXTEN = ".xu90" + +# Basic initialisation, will be used by the local script +SCRIPT_OPTIONS_DICT = {} + +# ## Local.py options for boundary layer ## + +SCRIPT_OPTIONS_DICT["bl_lsp"+str(FILE_EXTEN)] = { + "first_private_list": [ + "newqcf" + ] +} + +SCRIPT_OPTIONS_DICT["ex_flux_tq"+str(FILE_EXTEN)] = { + "options": { + "ignore_dependencies_for": [ + "bl_diag%grad_t_adj" + ] + }, + "first_private_list": [ + "f2_fqw", + "f2_ftl", + "fsc_fqw", + "fsc_ftl", + "non_grad_fqw", + "non_grad_ftl" + ] +} + +SCRIPT_OPTIONS_DICT["ex_flux_uv"+str(FILE_EXTEN)] = { + "options": { + "ignore_dependencies_for": [ + "tau_x_y" + ] + } +} + +SCRIPT_OPTIONS_DICT["tr_mix"+str(FILE_EXTEN)] = { + "options": { + "ignore_dependencies_for": [ + "f_field", + "rhok_dep", + "surf_dep_flux", + "gamma_rhokh_rdz" + ] + }, + "first_private_list": [ + "dfield_inv", + "dz_disc", + "dzlkp1", + "f_field_ent", + "km1" + ] +} + +SCRIPT_OPTIONS_DICT["bdy_impl3"+str(FILE_EXTEN)] = { + "options": { + "ignore_dependencies_for": [ + "dtl1_1", + "ct_prod", + "dqw1_1", + "dqw", + "dtl", + "ct_ctq", + "temp", + "dqw1", + "dtl1", + "ctctq1" + ] + }, + "safe_pure_calls": [ + "oneover_v" + ], + "max_threads_parse": True, + "loop_type_init": [ + "max_threads", + "blm1", + "tdims_omp_block", + "tdims_seg_block" + ] +} + +SCRIPT_OPTIONS_DICT["bdy_impl4"+str(FILE_EXTEN)] = { + "options": { + "ignore_dependencies_for": [ + "tl", + "qw", + "dtl", + "dqw" + ] + }, + "loop_type_init": [ + "tdims_omp_block", + "tdims_seg_block" + ] +} + +SCRIPT_OPTIONS_DICT["imp_mix"+str(FILE_EXTEN)] = { + "options": { + "ignore_dependencies_for": [ + "d_field", + "af", + "field", + "gamma_rhok_dep", + "f_field", + "surf_dep_flux" + ] + }, + "max_threads_parse": True, + "loop_type_init": [ + "max_threads", + "blm1", + "pdims_omp_block", + "pdims_seg_block" + ] +} + +SCRIPT_OPTIONS_DICT["fm_drag"+str(FILE_EXTEN)] = { + "options": { + "ignore_dependencies_for": [ + "k_for_buoy", + "u_hm", + "v_hm", + "tl_hm", + "qw_hm", + "tau_fd_x", + "tau_fd_y" + ] + }, + "first_private_list": [ + "fp_x_low", + "fp_x_steep", + "fp_y_low", + "fp_y_steep", + "rib_fn", + "tausx", + "tausy", + "wta", + "wtb" + ] +} + +# ## Other boundary layer options ## diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/global.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/global.py new file mode 100644 index 000000000..8e2479bd8 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/global.py @@ -0,0 +1,64 @@ +############################################################################## +# Copyright (c) 2025, Met Office, on behalf of HMSO and Queen's Printer +# For further details please refer to the file LICENCE.original which you +# should have received as part of this distribution. +############################################################################## +''' +A global script to add OpenMP to loops present in the file provided. +This script imports a SCRIPT_OPTIONS_DICT which can be used to override +small aspects of this script per file it is applied to. +Overrides currently include: +* Options list for transformations +* safe pure calls for loops over calls which can be parallelised +''' + +import logging +from psyclone.transformations import ( + TransformationError) +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + OMP_PARALLEL_LOOP_DO_TRANS_STATIC, + set_pure_subroutines, +) +from script_options import ( + SCRIPT_OPTIONS_DICT +) + + +def trans(psyir): + ''' + PSyclone function call, run through psyir object, + each schedule (or subroutine) and apply paralleldo transformations + to each loop. + ''' + + # options list for transformation. + options = {} + + # Designate calls in regions as safe to parallelise over. + safe_pure_calls = [] + + fortran_file_name = str(psyir.root.name) + # Check if file is in the script_options_dict + # Copy out anything that's needed + # options list and a pure calls override + if fortran_file_name in SCRIPT_OPTIONS_DICT: + file_overrides = SCRIPT_OPTIONS_DICT[fortran_file_name] + if "options" in file_overrides.keys(): + options = file_overrides["options"] + if "safe_pure_calls" in file_overrides.keys(): + safe_pure_calls = file_overrides["safe_pure_calls"] + + # Set the pure calls if needed + if safe_pure_calls: + set_pure_subroutines(psyir, safe_pure_calls) + + # Work through each loop in the file and OMP PARALLEL DO + for loop in psyir.walk(Loop): + if not loop.ancestor(Loop): + try: + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) + + except (TransformationError, IndexError) as err: + logging.warning( + "Could not transform because:\n %s", err) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py index cc3235be5..cf4b240ce 100644 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py @@ -1,8 +1,8 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. -############################################################################## +# ----------------------------------------------------------------------------- """ Optimisation script that adds OpenMP worksharing-loop directives to speed up loops before and after a PC2 subroutine call. Some PSyclone dependency errors diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/conv_gr_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/conv_gr_kernel_mod.py new file mode 100644 index 000000000..7a704a47f --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/conv_gr_kernel_mod.py @@ -0,0 +1,387 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +""" +PSyclone script for applying OpenMP transformations specific to the +Gregory-Rowntree convection kernel. +""" +import logging + +from psyclone.psyir.nodes import ( + Call, + Loop, + Node, + OMPParallelDoDirective, + Reference, + Routine, + OMPParallelDirective, + OMPDoDirective, +) +from psyclone.transformations import ( + OMPParallelLoopTrans, + TransformationError, +) + +from transmute_psytrans.transmute_functions import ( + first_priv_red_init, + get_compiler, + add_omp_parallel_region, +) + +logger = logging.getLogger(__name__) + + +def trans(psyir: Routine): + """ + Apply PSyClone OpenMP directives + + Transformation takes the following steps: + - Add OMPParallelDirective around marked loops with OMPParallelTrans + - Add OMPDoDirective to loops within the parallel regions with OMPLoopTrans + - Add OMPParallelDoDirective to loops outside the parallel regions with OMPParallelLoopTrans + + Special treatment required for the loop containing glue_conv_6a. + """ + + # Transformations + omp_trans_parallel_loop_static = OMPParallelLoopTrans( + omp_schedule="static", omp_directive="paralleldo" + ) + omp_trans_parallel_loop_dynamic = OMPParallelLoopTrans( + omp_schedule="dynamic", omp_directive="paralleldo" + ) + + default_trans_options = {"collapse": True} + if get_compiler() == "cce": + default_trans_options["collapse"] = False + loop_trans_options = default_trans_options | {"node-type-check": False} + + for routine in psyir.walk(Routine): + # Identify large parallel region + try: + callnumber_loop = next(filter(is_callnumber_loop, routine.children)) + except StopIteration: + logger.error("Call-number loop not found in routine.") + return + first_loop = next( + filter(lambda node: isinstance(node, Loop), routine.children) + ) + + case_loop = next( + filter( + lambda loop: "ntra_fld" in str(loop.stop_expr), + routine.walk(Loop), + ), + None, + ) + + loops_to_ignore = [case_loop] + + # Ignore nested wtrac loops except inner-most (i) loops to agree with old script + for loop in filter(is_wtrac_loop, routine.walk(Loop)): + loops_to_ignore.extend( + inner_loop + for inner_loop in loop.walk(Loop) + if inner_loop.variable.name != "i" + ) + + add_omp_parallel_region( + first_loop, + callnumber_loop, + end_offset=-2, + ignore_loops=loops_to_ignore, + loop_trans_options=loop_trans_options, + ) + + # Identify extra parallel regions (loops inside callnumber loop, up to numseg) + try: + numseg_loop = next(filter(is_numseg_loop, routine.walk(Loop))) + except StopIteration: + logger.error("Numseg loop not found in call-number loop.") + return + + callnumber_nested_loop = callnumber_loop.loop_body.children[0] + + add_omp_parallel_region( + callnumber_nested_loop, + numseg_loop, + end_offset=-2, + loop_trans_options=loop_trans_options, + ) + + # Special treatment of numseg loop for parallel do + + # Add "pure" property to specific symbols + for call in numseg_loop.walk(Call): + if call.routine.symbol.name in ["glue_conv_6a", "log_event"]: + call.routine.symbol.is_pure = True + try: + omp_trans_parallel_loop_dynamic.apply( + numseg_loop, + options=loop_trans_options, + ) + except TransformationError as e: + logger.warning(e) + + for loop in routine.walk(Loop): + # Identify each loop in the routine and add OMPParallelDoDirective to outer loops + + # Ignore specific outer loops (their inner loops will still be transformed) + if loop.variable.name in ["call_number"]: + continue + + # Don't attempt to nest parallel directives + if ( + loop.ancestor(OMPParallelDoDirective) is not None + or loop.ancestor(OMPDoDirective) is not None + or loop.ancestor(OMPParallelDirective) is not None + ): + continue + + # Main transformations: + # Add OMPParallelDoDirective outside OMPParallelDirective regions + try: + omp_trans_parallel_loop_static.apply( + loop, + options=default_trans_options + | { + "ignore_dependencies_for": ( + ignore_dependencies_block2_after_numseg + + ignore_dependencies_block3 + ), + }, + ) + except TransformationError as e: + logger.warning(e) + + # Fix for firstprivate initialisation bug with CCE + if get_compiler() == "cce": + first_private_list = ["k", "conv_active", "orig_value"] + for node in routine.children: + if isinstance(node, OMPParallelDirective): + first_priv_red_init(node, first_private_list) + break + + +def is_numseg_loop(node: Node): + """ + Check if node is the num_seg loop: "do i = 1, num_seg" + """ + return ( + isinstance(node, Loop) + and node.variable.name == "i" + and any(ref.name == "num_seg" for ref in node.stop_expr.walk(Reference)) + ) + + +def is_callnumber_loop(node: Node): + """ + Check if node is the call_number loop: "do call_number = 1, n_conv_calls" + """ + return ( + isinstance(node, Loop) + and node.variable.name == "call_number" + and any( + ref.name == "n_conv_calls" for ref in node.stop_expr.walk(Reference) + ) + ) + + +def is_wtrac_loop(node: Node): + """ + Check if node is a n_wtrac loop: "do _ = 1, n_wtrac, 1" + """ + return isinstance(node, Loop) and any( + ref.name == "n_wtrac" for ref in node.stop_expr.walk(Reference) + ) + + +ignore_dependencies_block2_after_numseg = [ + "conv_rain", + "conv_snow", + "cca_2d", + "cape_diluted", + "lowest_cca_2d", + "deep_in_col", + "shallow_in_col", + "mid_in_col", + "freeze_level", + "deep_prec", + "shallow_prec", + "mid_prec", + "deep_term", + "cape_timescale", + "deep_cfl_limited", + "mid_cfl_limited", + "deep_tops", + "dt_conv", + "dmv_conv", + "dmcl_conv", + "dms_conv", + "massflux_up", + "massflux_down", + "conv_rain_3d", + "conv_snow_3d", + "entrain_up", + "entrain_down", + "detrain_up", + "detrain_down", + "dd_dt", + "dd_dq", + "deep_massflux", + "deep_dt", + "deep_dq", + "shallow_massflux", + "shallow_dt", + "shallow_dq", + "mid_massflux", + "mid_dt", + "mid_dq", + "cca_unadjusted", + "massflux_up_half", + "du_conv", + "dv_conv", +] + +ignore_dependencies_block3 = [ + "o3p", + "o1d", + "o3", + "nit", + "no", + "no3", + "lumped_n", + "n2o5", + "ho2no2", + "hono2", + "h2o2", + "ch4", + "co", + "hcho", + "meoo", + "meooh", + "h", + "oh", + "ho2", + "cl", + "cl2o2", + "clo", + "oclo", + "br", + "lumped_br", + "brcl", + "brono2", + "n2o", + "lumped_cl", + "hocl", + "hbr", + "hobr", + "clono2", + "cfcl3", + "cf2cl2", + "mebr", + "hono", + "c2h6", + "etoo", + "etooh", + "mecho", + "meco3", + "pan", + "c3h8", + "n_proo", + "i_proo", + "n_prooh", + "i_prooh", + "etcho", + "etco3", + "me2co", + "mecoch2oo", + "mecoch2ooh", + "ppan", + "meono2", + "c5h8", + "iso2", + "isooh", + "ison", + "macr", + "macro2", + "macrooh", + "mpan", + "hacet", + "mgly", + "nald", + "hcooh", + "meco3h", + "meco2h", + "h2", + "meoh", + "msa", + "nh3", + "cs2", + "csul", + "h2s", + "so3", + "passive_o3", + "age_of_air", + "dms", + "so2", + "h2so4", + "dmso", + "monoterpene", + "secondary_organic", + "n_nuc_sol", + "nuc_sol_su", + "nuc_sol_om", + "n_ait_sol", + "ait_sol_su", + "ait_sol_bc", + "ait_sol_om", + "n_acc_sol", + "acc_sol_su", + "acc_sol_bc", + "acc_sol_om", + "acc_sol_ss", + "n_cor_sol", + "cor_sol_su", + "cor_sol_bc", + "cor_sol_om", + "cor_sol_ss", + "n_ait_ins", + "ait_ins_bc", + "ait_ins_om", + "n_acc_ins", + "acc_ins_du", + "n_cor_ins", + "cor_ins_du", + "dmv_conv", + "conv_prog_precip", + "conv_prog_precip", + "dt_conv", + "conv_prog_dtheta", + "dmv_conv", + "conv_prog_dmv", + "dcfl_conv", + "dcff_conv", + "dbcf_conv", + "dt_conv", + "dmv_conv", + "dmcl_conv", + "dms_conv", + "dd_mf_cb", + "cca", + "ccw", + "cv_top", + "cv_base", + "lowest_cv_top", + "lowest_cv_base", + "pres_cv_top", + "pres_cv_base", + "pres_lowest_cv_top", + "pres_lowest_cv_base", + "massflux_up_cmpta", + "dth_conv_noshal", + "dmv_conv_noshal", + "tke_bl", +] diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_exp_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_exp_kernel_mod.py index 7c28ef7f4..e63362014 100644 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_exp_kernel_mod.py +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_exp_kernel_mod.py @@ -1,8 +1,8 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. -############################################################################## +# ----------------------------------------------------------------------------- ''' Bespoke PSyclone transformation script for jules_imp_kernel_mod. ''' @@ -21,10 +21,11 @@ SAFE_IMPURE_CALLS = ["qsat_mix"] + def trans(psyir): ''' PSyclone function call, run through psyir object, - each schedul e(or subroutine) and apply OMP paralleldo transformations + each schedule (or subroutine) and apply OMP paralleldo transformations to each loop in jules_imp_kernel_mod. ''' @@ -36,7 +37,6 @@ def trans(psyir): "sea_ice_pensolar", "rhostar_2d", "recip_l_mo_sea_2d", - "h_blend_orog_2d", "t1_sd_2d", "q1_sd_2d", "surf_interp", @@ -81,7 +81,6 @@ def trans(psyir): impure_calls = [c for c in loop.walk(Call) if not c.is_pure] for call in impure_calls: if call.routine.symbol.name in SAFE_IMPURE_CALLS: - print(call.routine.name) call.routine.symbol.is_pure = True omp_transform_par_do.apply(loop, options) @@ -89,5 +88,7 @@ def trans(psyir): logging.warning( "Could not transform because:\n %s", err) -#Ignore loops setting these as order dependent: land_field l ainfo%land_index sea_pts ainfo%sea_index ainfo%sice_pts_ncat ainfo%sice_index_ncat -#Ignore as calls subroutine: qsat_mix +# Ignore loops setting these as order dependent: +# land_field l ainfo%land_index sea_pts ainfo%sea_index +# ainfo%sice_pts_ncat ainfo%sice_index_ncat +# Ignore as calls subroutine: qsat_mix diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_extra_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_extra_kernel_mod.py index 783dbf800..87052696b 100644 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_extra_kernel_mod.py +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_extra_kernel_mod.py @@ -1,8 +1,8 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. -############################################################################## +# ----------------------------------------------------------------------------- ''' Bespoke PSyclone transformation script for jules_extra_kernel_mod. ''' @@ -63,4 +63,6 @@ def trans(psyir): logging.warning( "Could not transform because:\n %s", err) -#Ignore loops setting these as order dependent: land_pts l ainfo%land_index soil_pts ainfo%soil_index lice_pts ainfo%lice_index +# Ignore loops setting these as order dependent: +# land_pts l ainfo%land_index soil_pts +# ainfo%soil_index lice_pts ainfo%lice_index diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_imp_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_imp_kernel_mod.py index dff5f1311..c1a880515 100644 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_imp_kernel_mod.py +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/jules_imp_kernel_mod.py @@ -1,8 +1,8 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. -############################################################################## +# ----------------------------------------------------------------------------- ''' Bespoke PSyclone transformation script for jules_imp_kernel_mod. ''' @@ -11,7 +11,7 @@ from psyclone.transformations import ( OMPLoopTrans, TransformationError) -from psyclone.psyir.nodes import Loop, IfBlock, Schedule +from psyclone.psyir.nodes import Loop, IfBlock omp_transform_par_do = OMPLoopTrans( @@ -88,9 +88,11 @@ def trans(psyir): if descendent is not loop] if loop_descendents[0].loop_type == 'l': # Now check if there are any if statements in this loop - if_statements = [descendent for descendent in - loop_descendents[0].walk(IfBlock, depth=None) - if descendent is not loop] + if_statements = [ + descendent for descendent in + loop_descendents[0].walk(IfBlock, depth=None) + if descendent is not loop + ] # There is only one loop like this so we can just skip the # transformation for it if len(if_statements) > 0: @@ -105,5 +107,6 @@ def trans(psyir): logging.warning( "Could not transform:\n %s", err) -#Ignore loops setting these as order dependent: land_field l ainfo%land_index sice_pts ainfo%sice_index sea_pts ainfo%sea_inde ainfo%sice_pts_ncat - +# Ignore loops setting these as order dependent: +# land_field l ainfo%land_index sice_pts ainfo%sice_index +# sea_pts ainfo%sea_inde ainfo%sice_pts_ncat diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/mphys_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/mphys_kernel_mod.py deleted file mode 100644 index 41c3d5c95..000000000 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/mphys_kernel_mod.py +++ /dev/null @@ -1,72 +0,0 @@ -############################################################################## -# Copyright (c) 2025, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## -''' -Bespoke Opt script for mphys_kernel_mod to add OpenMP to loops present in -the Kernel. -As PSyclone is detecting a number of lhs rhs dependencies due to the -copies in and out of the kernel, we are needing to provide a list of -ignore_dependencies_for in the transformation options list. -''' - -import logging -from psyclone.transformations import ( - OMPLoopTrans, - TransformationError) -from psyclone.psyir.nodes import Loop - - -omp_transform_par_do = OMPLoopTrans( - omp_schedule="static", - omp_directive="paralleldo") - - -def trans(psyir): - ''' - PSyclone function call, run through psyir object, - each schedule (or subroutine) and apply paralleldo transformations - to each loop in large scale precip. - ''' - - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - options = {"ignore_dependencies_for": [ - "dtheta", # First and Second i, k loop - "dmv_wth", # First and Second i, k loop - "dml_wth", # First and Second i, k loop - "dms_wth", # First and Second i, k loop - "dmr_wth", # Third i, k loop - "dmg_wth", # Forth i, k loop - "murk", # First k, i loop - "dbcf_wth", # Fifth i, k loop - "dcfl_wth", # Fifth i, k loop - "dcff_wth", # Fifth i, k loop - "ls_rain_2d", # Fifth i, k loop - "ls_snow_2d", # Fifth i, k loop - "ls_graup_2d", # Fifth i, k loop - "lsca_2d", # Fifth i, k loop - "ls_rain_3d", # Fifth i, k loop - "ls_snow_3d", # Fifth i, k loop - "precfrac", # Fifth i, k loop - "refl_tot", # Fifth i, k loop - "autoconv", # Fifth i, k loop - "accretion", # Fifth i, k loop - "rim_cry", # Fifth i, k loop - "rim_agg", # Fifth i, k loop - "refl_1km", # Fifth i, k loop - "superc_liq_wth", # Sixth i, k loop - "superc_rain_wth", # Seventh i, k loop - "sfwater", # Eighth i, k loop - "sfwater", # Second k, i loop - "sfrain", # Third k, i loop - "sfsnow", # Fourth k, i loop - ], - "node-type-check": False} - try: - omp_transform_par_do.apply(loop, options) - - except (TransformationError, IndexError) as err: - logging.warning( - "Could not transform because:\n %s", err) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py index d7748acfa..5ce26ee90 100644 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py @@ -1,8 +1,8 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. -############################################################################## +# ----------------------------------------------------------------------------- """ Optimisation script that adds OpenMP parallel do worksharing-loop directives. The main loop requires dynamic schedule to improve load balancing between diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py index ed4a0e90e..c1eddb8f2 100644 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py @@ -1,8 +1,8 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. -############################################################################## +# ----------------------------------------------------------------------------- """ Optimisation script that adds OpenMP worksharing-loop directives to speed up various loops. Some PSyclone dependency errors need to be overridden; these diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/sw_rad_tile_kernel_mod.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/sw_rad_tile_kernel_mod.py index a8a2210a6..ceff34094 100644 --- a/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/sw_rad_tile_kernel_mod.py +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/kernel/sw_rad_tile_kernel_mod.py @@ -1,8 +1,8 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. # The file LICENCE, distributed with this code, contains details of the terms # under which the code may be used. -############################################################################## +# ----------------------------------------------------------------------------- ''' Bespoke PSyclone transformation script for sw_rad_tile_kernel_mod. ''' @@ -44,4 +44,6 @@ def trans(psyir): logging.warning( "Could not transform because:\n %s", err) -#Ignore loops setting these as order dependent: land_field l ainfo%land_index sea_pts ainfo%sea_index ainfo%sice_pts_ncat ainfo%sice_index_ncat +# Ignore loops setting these as order dependent: +# land_field l ainfo%land_index sea_pts +# ainfo%sea_index ainfo%sice_pts_ncat ainfo%sice_index_ncat diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_bl_forced_cu.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_bl_forced_cu.py new file mode 100644 index 000000000..b34a512f6 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_bl_forced_cu.py @@ -0,0 +1,47 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to target loops over index i instead of +index j. Trip count of j loops is 1 in LFRic, which prevents parallel +execution. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + get_outer_loops, + get_compiler, + first_priv_red_init, + OMP_PARALLEL_LOOP_DO_TRANS_DYNAMIC, + OMP_PARALLEL_LOOP_DO_TRANS_STATIC +) + + +def trans(psyir): + """ + Apply OpenMP Directives + """ + + # Identify outer loops + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + # Apply OpenMP parallel do directives and use workaround for + # firstprivate variable issue; replicate dynamic and static + # schedules of the original implementation + try: + for idx, loop in enumerate(outer_loops): + if get_compiler() == 'cce': + first_priv_red_init(loop, ["cf_base", "cf_forced", "dcfl", + "dqcl", "qcl_forced", "qcl_tol"]) + if idx == 0: + OMP_PARALLEL_LOOP_DO_TRANS_DYNAMIC.apply(loop.walk(Loop)[1]) + else: + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop.walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_bm_initiate.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_bm_initiate.py new file mode 100644 index 000000000..b1286eb05 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_bm_initiate.py @@ -0,0 +1,145 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to target loops over index i instead of +index j. Trip count of j loops is 1 in LFRic, which prevents parallel +execution. Private variables need to be declared explicitly as PSyclone +analysis currently misses a scalar variable that a subroutine modifies in +a parallel region. PSyclone thread safety checks need to be overridden; +the subroutines can be safely parallelised. Compiler directives used in +the original code are re-inserted for performance and consistency of output. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import (Loop, CodeBlock) +from transmute_psytrans.transmute_functions import ( + set_pure_subroutines, + get_outer_loops, + mark_explicit_privates, + get_compiler, + first_priv_red_init, + match_lhs_assignments, + match_call_args, + OMP_PARALLEL_REGION_TRANS, + OMP_DO_LOOP_TRANS_STATIC +) + +# Variables in parallel region that need to be private +private_variables = [ + "alphal", "alx", "i", "j", "k", "km1", "kp1", "mux", "tmp", + "frac_init", "kk", "kkm1", "kkp1", "qc", "qc_points", "qsl", + "tlx", "qsi", "idx", "deltacl_c", "deltacf_c", "deltaql_c", + "cf_c", "cfl_c", "cff_c" +] + +# Subroutines that need to be declared as "pure" +pure_subroutines = ["qsat", "qsat_mix", "qsat_wat", "qsat_wat_mix"] + +# Variables that appear on the left-hand side of assignments +# or as call arguments for which PSyclone dependency errors +# can be ignored +false_dep_vars = [ + "qc_points", + "idx", + "tl_in", + "p_theta_levels", + "qsi_lay", + "qsl_lay", +] + + +class CompilerDirective(): + """ + Custom compiler directive class to avoid an issue + with fparser.two.Fortran2003.Directive that will + be resolved in an upcoming fparser release. + """ + def __init__(self, directive): + self.directive = directive + + def tofortran(self): + """ + Return directive with prefix + """ + return "!DIR$ " + self.directive + + +def trans(psyir): + """ + Apply OpenMP and Compiler Directives + """ + + # Declare subroutines as pure to enable parallelisation + # of the encompassing loops + set_pure_subroutines(psyir, pure_subroutines) + + # Identify outer loops for setting up parallel regions + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + # Check if first OpenMP region can be parallelised and + # apply directives + try: + OMP_PARALLEL_REGION_TRANS.validate(outer_loops[0:2]) + OMP_PARALLEL_REGION_TRANS.apply(outer_loops[0:2]) + OMP_DO_LOOP_TRANS_STATIC.apply(outer_loops[0]) + OMP_DO_LOOP_TRANS_STATIC.apply(outer_loops[1].walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("Parallelisation of the 1st region failed: %s", err) + + # Declare private symbols for the last loop nest explicitly, + # PSyclone misses one + mark_explicit_privates(outer_loops[2], private_variables) + + # Parallelise the second region and insert compiler directives + # Add redundant variable initialisation to work around a known + # PSyclone issue when using CCE + try: + if get_compiler() == 'cce': + first_priv_red_init(outer_loops[2], ["i", "j", "k"]) + + OMP_PARALLEL_REGION_TRANS.validate(outer_loops[2:3]) + OMP_PARALLEL_REGION_TRANS.apply(outer_loops[2]) + + # Insert before OpenMP directives to avoid PSyclone errors + if get_compiler() == "cce": + for loop in outer_loops[2].walk(Loop)[3:5]: + cblock = CodeBlock([CompilerDirective("NOFISSION")], + CodeBlock.Structure.STATEMENT) + insert_at = loop.parent.children.index(loop) + loop.parent.children.insert(insert_at, cblock) + + for loop in outer_loops[2].walk(Loop)[13:16]: + cblock = CodeBlock([CompilerDirective("IVDEP")], + CodeBlock.Structure.STATEMENT) + insert_at = loop.parent.children.index(loop) + loop.parent.children.insert(insert_at, cblock) + + for loop in outer_loops[2].walk(Loop)[2:7]: + # Check if any eligible variables appear in subroutine + # call arguments; these lead to false dependency errors + # in the parallel loop transformation that can be + # ignored + ignore_deps_vars = match_call_args(loop, false_dep_vars) + options = {} + if len(ignore_deps_vars) > 0: + options["ignore_dependencies_for"] = ignore_deps_vars + OMP_DO_LOOP_TRANS_STATIC.apply(loop, options) + + for loop in outer_loops[2].walk(Loop)[8:13:2]: + # Check if any eligible variables appear on the LHS of + # assignment expressions to ignore false dependency errors + ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) + options = {} + if len(ignore_deps_vars) > 0: + options["ignore_dependencies_for"] = ignore_deps_vars + + OMP_DO_LOOP_TRANS_STATIC.apply(loop, options) + + except (TransformationError, IndexError) as err: + logging.warning("Parallelisation of the 2nd region failed: %s", err) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_initiation_ctl.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_initiation_ctl.py new file mode 100644 index 000000000..f0d19a243 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/large_scale_cloud/pc2_initiation_ctl.py @@ -0,0 +1,37 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to parallelise additional loops. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + get_outer_loops, + OMP_PARALLEL_LOOP_DO_TRANS_STATIC, +) + + +def trans(psyir): + """ + Apply OpenMP Directives + """ + + # Identify outer loops in the subroutine + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + try: + # Parallelise k-loops and i-loops (j-loops have a trip count of 1) + for loop in outer_loops: + if loop.variable.name == 'k': + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop) + elif loop.variable.name == 'j': + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop.walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/lfric_atm/optimisation/meto-ex1a/transmute/script_options.py b/applications/lfric_atm/optimisation/meto-ex1a/transmute/script_options.py new file mode 100644 index 000000000..c2685d3e1 --- /dev/null +++ b/applications/lfric_atm/optimisation/meto-ex1a/transmute/script_options.py @@ -0,0 +1,57 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +''' +Lift options list and similar from each individual script up into this file. +Aim is to allow the creation of a simple global.py which adds OMP over all +loops. The option which matches the file being worked on can be pulled in +and referenced. This reduces the number of files needed +''' + +# Needs to be lifted and likely set by the build system longer term. +# The filename passed to PSyclone, this is the pre-processed FTN source. +FILE_EXTEN = ".xu90" + +# Basic initialisation, will be used by global script +SCRIPT_OPTIONS_DICT = {} + +# Kernels +SCRIPT_OPTIONS_DICT["mphys_kernel_mod"+str(FILE_EXTEN)] = { + + "options": { + "node-type-check": False, + "ignore_dependencies_for": [ + "dtheta", # First and Second i, k loop + "dmv_wth", # First and Second i, k loop + "dml_wth", # First and Second i, k loop + "dms_wth", # First and Second i, k loop + "dmr_wth", # Third i, k loop + "dmg_wth", # Forth i, k loop + "murk", # First k, i loop + "dbcf_wth", # Fifth i, k loop + "dcfl_wth", # Fifth i, k loop + "dcff_wth", # Fifth i, k loop + "ls_rain_2d", # Fifth i, k loop + "ls_snow_2d", # Fifth i, k loop + "ls_graup_2d", # Fifth i, k loop + "lsca_2d", # Fifth i, k loop + "ls_rain_3d", # Fifth i, k loop + "ls_snow_3d", # Fifth i, k loop + "precfrac", # Fifth i, k loop + "refl_tot", # Fifth i, k loop + "autoconv", # Fifth i, k loop + "accretion", # Fifth i, k loop + "rim_cry", # Fifth i, k loop + "rim_agg", # Fifth i, k loop + "refl_1km", # Fifth i, k loop + "superc_liq_wth", # Sixth i, k loop + "superc_rain_wth", # Seventh i, k loop + "sfwater", # Eighth i, k loop + "sfwater", # Second k, i loop + "sfrain", # Third k, i loop + "sfsnow", # Fourth k, i loop + ] + } +} diff --git a/applications/lfric_atm/optimisation/ncas-ex/psykal/algorithm/conv_gr_alg_mod.py b/applications/lfric_atm/optimisation/ncas-ex/psykal/algorithm/conv_gr_alg_mod.py new file mode 100644 index 000000000..43bca89f4 --- /dev/null +++ b/applications/lfric_atm/optimisation/ncas-ex/psykal/algorithm/conv_gr_alg_mod.py @@ -0,0 +1,25 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +""" +PSyclone transformation script for the LFRic (Dynamo0p3) API to apply +colouring and redundant computation to the level-1 halo for +the initialisation built-ins generically. +""" + +from psyclone_tools import redundant_computation_setval, colour_loops, view_transformed_schedule + + +def trans(psyir): + """ + Applies PSyclone colouring and redundant computation transformations. + + :param psyir: the PSyIR of the PSy-layer. + :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` + + """ + redundant_computation_setval(psyir) + colour_loops(psyir) + view_transformed_schedule(psyir) diff --git a/applications/lfric_atm/optimisation/ncas-ex/transmute/global.py b/applications/lfric_atm/optimisation/ncas-ex/transmute/global.py new file mode 100644 index 000000000..3689181e3 --- /dev/null +++ b/applications/lfric_atm/optimisation/ncas-ex/transmute/global.py @@ -0,0 +1,9 @@ +############################################################################## +# Copyright (c) 2025, Met Office, on behalf of HMSO and Queen's Printer +# For further details please refer to the file LICENCE.original which you +# should have received as part of this distribution. +############################################################################## +''' +Placeholder script to ensure site is unaffected by changes. +Owners of site target should update this as required. +''' \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/ncas-ex/transmute/kernel/conv_gr_kernel_mod.py b/applications/lfric_atm/optimisation/ncas-ex/transmute/kernel/conv_gr_kernel_mod.py new file mode 100644 index 000000000..7a704a47f --- /dev/null +++ b/applications/lfric_atm/optimisation/ncas-ex/transmute/kernel/conv_gr_kernel_mod.py @@ -0,0 +1,387 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +""" +PSyclone script for applying OpenMP transformations specific to the +Gregory-Rowntree convection kernel. +""" +import logging + +from psyclone.psyir.nodes import ( + Call, + Loop, + Node, + OMPParallelDoDirective, + Reference, + Routine, + OMPParallelDirective, + OMPDoDirective, +) +from psyclone.transformations import ( + OMPParallelLoopTrans, + TransformationError, +) + +from transmute_psytrans.transmute_functions import ( + first_priv_red_init, + get_compiler, + add_omp_parallel_region, +) + +logger = logging.getLogger(__name__) + + +def trans(psyir: Routine): + """ + Apply PSyClone OpenMP directives + + Transformation takes the following steps: + - Add OMPParallelDirective around marked loops with OMPParallelTrans + - Add OMPDoDirective to loops within the parallel regions with OMPLoopTrans + - Add OMPParallelDoDirective to loops outside the parallel regions with OMPParallelLoopTrans + + Special treatment required for the loop containing glue_conv_6a. + """ + + # Transformations + omp_trans_parallel_loop_static = OMPParallelLoopTrans( + omp_schedule="static", omp_directive="paralleldo" + ) + omp_trans_parallel_loop_dynamic = OMPParallelLoopTrans( + omp_schedule="dynamic", omp_directive="paralleldo" + ) + + default_trans_options = {"collapse": True} + if get_compiler() == "cce": + default_trans_options["collapse"] = False + loop_trans_options = default_trans_options | {"node-type-check": False} + + for routine in psyir.walk(Routine): + # Identify large parallel region + try: + callnumber_loop = next(filter(is_callnumber_loop, routine.children)) + except StopIteration: + logger.error("Call-number loop not found in routine.") + return + first_loop = next( + filter(lambda node: isinstance(node, Loop), routine.children) + ) + + case_loop = next( + filter( + lambda loop: "ntra_fld" in str(loop.stop_expr), + routine.walk(Loop), + ), + None, + ) + + loops_to_ignore = [case_loop] + + # Ignore nested wtrac loops except inner-most (i) loops to agree with old script + for loop in filter(is_wtrac_loop, routine.walk(Loop)): + loops_to_ignore.extend( + inner_loop + for inner_loop in loop.walk(Loop) + if inner_loop.variable.name != "i" + ) + + add_omp_parallel_region( + first_loop, + callnumber_loop, + end_offset=-2, + ignore_loops=loops_to_ignore, + loop_trans_options=loop_trans_options, + ) + + # Identify extra parallel regions (loops inside callnumber loop, up to numseg) + try: + numseg_loop = next(filter(is_numseg_loop, routine.walk(Loop))) + except StopIteration: + logger.error("Numseg loop not found in call-number loop.") + return + + callnumber_nested_loop = callnumber_loop.loop_body.children[0] + + add_omp_parallel_region( + callnumber_nested_loop, + numseg_loop, + end_offset=-2, + loop_trans_options=loop_trans_options, + ) + + # Special treatment of numseg loop for parallel do + + # Add "pure" property to specific symbols + for call in numseg_loop.walk(Call): + if call.routine.symbol.name in ["glue_conv_6a", "log_event"]: + call.routine.symbol.is_pure = True + try: + omp_trans_parallel_loop_dynamic.apply( + numseg_loop, + options=loop_trans_options, + ) + except TransformationError as e: + logger.warning(e) + + for loop in routine.walk(Loop): + # Identify each loop in the routine and add OMPParallelDoDirective to outer loops + + # Ignore specific outer loops (their inner loops will still be transformed) + if loop.variable.name in ["call_number"]: + continue + + # Don't attempt to nest parallel directives + if ( + loop.ancestor(OMPParallelDoDirective) is not None + or loop.ancestor(OMPDoDirective) is not None + or loop.ancestor(OMPParallelDirective) is not None + ): + continue + + # Main transformations: + # Add OMPParallelDoDirective outside OMPParallelDirective regions + try: + omp_trans_parallel_loop_static.apply( + loop, + options=default_trans_options + | { + "ignore_dependencies_for": ( + ignore_dependencies_block2_after_numseg + + ignore_dependencies_block3 + ), + }, + ) + except TransformationError as e: + logger.warning(e) + + # Fix for firstprivate initialisation bug with CCE + if get_compiler() == "cce": + first_private_list = ["k", "conv_active", "orig_value"] + for node in routine.children: + if isinstance(node, OMPParallelDirective): + first_priv_red_init(node, first_private_list) + break + + +def is_numseg_loop(node: Node): + """ + Check if node is the num_seg loop: "do i = 1, num_seg" + """ + return ( + isinstance(node, Loop) + and node.variable.name == "i" + and any(ref.name == "num_seg" for ref in node.stop_expr.walk(Reference)) + ) + + +def is_callnumber_loop(node: Node): + """ + Check if node is the call_number loop: "do call_number = 1, n_conv_calls" + """ + return ( + isinstance(node, Loop) + and node.variable.name == "call_number" + and any( + ref.name == "n_conv_calls" for ref in node.stop_expr.walk(Reference) + ) + ) + + +def is_wtrac_loop(node: Node): + """ + Check if node is a n_wtrac loop: "do _ = 1, n_wtrac, 1" + """ + return isinstance(node, Loop) and any( + ref.name == "n_wtrac" for ref in node.stop_expr.walk(Reference) + ) + + +ignore_dependencies_block2_after_numseg = [ + "conv_rain", + "conv_snow", + "cca_2d", + "cape_diluted", + "lowest_cca_2d", + "deep_in_col", + "shallow_in_col", + "mid_in_col", + "freeze_level", + "deep_prec", + "shallow_prec", + "mid_prec", + "deep_term", + "cape_timescale", + "deep_cfl_limited", + "mid_cfl_limited", + "deep_tops", + "dt_conv", + "dmv_conv", + "dmcl_conv", + "dms_conv", + "massflux_up", + "massflux_down", + "conv_rain_3d", + "conv_snow_3d", + "entrain_up", + "entrain_down", + "detrain_up", + "detrain_down", + "dd_dt", + "dd_dq", + "deep_massflux", + "deep_dt", + "deep_dq", + "shallow_massflux", + "shallow_dt", + "shallow_dq", + "mid_massflux", + "mid_dt", + "mid_dq", + "cca_unadjusted", + "massflux_up_half", + "du_conv", + "dv_conv", +] + +ignore_dependencies_block3 = [ + "o3p", + "o1d", + "o3", + "nit", + "no", + "no3", + "lumped_n", + "n2o5", + "ho2no2", + "hono2", + "h2o2", + "ch4", + "co", + "hcho", + "meoo", + "meooh", + "h", + "oh", + "ho2", + "cl", + "cl2o2", + "clo", + "oclo", + "br", + "lumped_br", + "brcl", + "brono2", + "n2o", + "lumped_cl", + "hocl", + "hbr", + "hobr", + "clono2", + "cfcl3", + "cf2cl2", + "mebr", + "hono", + "c2h6", + "etoo", + "etooh", + "mecho", + "meco3", + "pan", + "c3h8", + "n_proo", + "i_proo", + "n_prooh", + "i_prooh", + "etcho", + "etco3", + "me2co", + "mecoch2oo", + "mecoch2ooh", + "ppan", + "meono2", + "c5h8", + "iso2", + "isooh", + "ison", + "macr", + "macro2", + "macrooh", + "mpan", + "hacet", + "mgly", + "nald", + "hcooh", + "meco3h", + "meco2h", + "h2", + "meoh", + "msa", + "nh3", + "cs2", + "csul", + "h2s", + "so3", + "passive_o3", + "age_of_air", + "dms", + "so2", + "h2so4", + "dmso", + "monoterpene", + "secondary_organic", + "n_nuc_sol", + "nuc_sol_su", + "nuc_sol_om", + "n_ait_sol", + "ait_sol_su", + "ait_sol_bc", + "ait_sol_om", + "n_acc_sol", + "acc_sol_su", + "acc_sol_bc", + "acc_sol_om", + "acc_sol_ss", + "n_cor_sol", + "cor_sol_su", + "cor_sol_bc", + "cor_sol_om", + "cor_sol_ss", + "n_ait_ins", + "ait_ins_bc", + "ait_ins_om", + "n_acc_ins", + "acc_ins_du", + "n_cor_ins", + "cor_ins_du", + "dmv_conv", + "conv_prog_precip", + "conv_prog_precip", + "dt_conv", + "conv_prog_dtheta", + "dmv_conv", + "conv_prog_dmv", + "dcfl_conv", + "dcff_conv", + "dbcf_conv", + "dt_conv", + "dmv_conv", + "dmcl_conv", + "dms_conv", + "dd_mf_cb", + "cca", + "ccw", + "cv_top", + "cv_base", + "lowest_cv_top", + "lowest_cv_base", + "pres_cv_top", + "pres_cv_base", + "pres_lowest_cv_top", + "pres_lowest_cv_base", + "massflux_up_cmpta", + "dth_conv_noshal", + "dmv_conv_noshal", + "tke_bl", +] diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/aerosol_ukca_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/aerosol_ukca_alg_mod.py index 04f6e8991..679150724 120000 --- a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/aerosol_ukca_alg_mod.py +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/aerosol_ukca_alg_mod.py @@ -1 +1 @@ -./../../../meto-ex1a/psykal/algorithm/aerosol_ukca_alg_mod.py \ No newline at end of file +../../../meto-ex1a/psykal/algorithm/aerosol_ukca_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/bl_imp_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/bl_imp_alg_mod.py index 002bb3751..e614250df 120000 --- a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/bl_imp_alg_mod.py +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/bl_imp_alg_mod.py @@ -1 +1 @@ -./../../../meto-ex1a/psykal/algorithm/bl_imp_alg_mod.py \ No newline at end of file +../../../meto-ex1a/psykal/algorithm/bl_imp_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/casim_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/casim_alg_mod.py index 04a064519..0aa4d7a59 120000 --- a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/casim_alg_mod.py +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/casim_alg_mod.py @@ -1 +1 @@ -./../../../meto-ex1a/psykal/algorithm/casim_alg_mod.py \ No newline at end of file +../../../meto-ex1a/psykal/algorithm/casim_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/checksum_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/checksum_alg_mod.py index 451c9586a..c9f9f6502 120000 --- a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/checksum_alg_mod.py +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/checksum_alg_mod.py @@ -1 +1 @@ -./../../../meto-ex1a/psykal/algorithm/checksum_alg_mod.py \ No newline at end of file +../../../meto-ex1a/psykal/algorithm/checksum_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/conv_comorph_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/conv_comorph_alg_mod.py new file mode 120000 index 000000000..b28c1682d --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/conv_comorph_alg_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/psykal/algorithm/conv_comorph_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/conv_gr_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/conv_gr_alg_mod.py new file mode 120000 index 000000000..eabfbaa3b --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/conv_gr_alg_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/psykal/algorithm/conv_gr_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/runtime_constants/physics_constants_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/runtime_constants/physics_constants_mod.py new file mode 120000 index 000000000..7a552184e --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/runtime_constants/physics_constants_mod.py @@ -0,0 +1 @@ +../../../../meto-ex1a/psykal/algorithm/runtime_constants/physics_constants_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/skeb_main_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/skeb_main_alg_mod.py new file mode 120000 index 000000000..52e0e341a --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/skeb_main_alg_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/psykal/algorithm/skeb_main_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/spt_main_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/spt_main_alg_mod.py new file mode 120000 index 000000000..7dfc313ea --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/spt_main_alg_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/psykal/algorithm/spt_main_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/transport/ffsl/ffsl_advective_updates_alg_mod.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/transport/ffsl/ffsl_advective_updates_alg_mod.py new file mode 120000 index 000000000..40c17efa5 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/algorithm/transport/ffsl/ffsl_advective_updates_alg_mod.py @@ -0,0 +1 @@ +../../../../../meto-ex1a/psykal/algorithm/transport/ffsl/ffsl_advective_updates_alg_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/psykal/global.py b/applications/lfric_atm/optimisation/nci-gadi/psykal/global.py index 7246d03a8..982b2e0cb 120000 --- a/applications/lfric_atm/optimisation/nci-gadi/psykal/global.py +++ b/applications/lfric_atm/optimisation/nci-gadi/psykal/global.py @@ -1 +1 @@ -./../../meto-ex1a/psykal/global.py \ No newline at end of file +../../meto-ex1a/psykal/global.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/bl_diags_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/bl_diags_mod.py new file mode 120000 index 000000000..2c217bd54 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/bl_diags_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/boundary_layer/bl_diags_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/kmkhz_9c_wtrac.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/kmkhz_9c_wtrac.py new file mode 120000 index 000000000..12a465a66 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/kmkhz_9c_wtrac.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/boundary_layer/kmkhz_9c_wtrac.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/local.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/local.py new file mode 120000 index 000000000..5edcbfa60 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/local.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/boundary_layer/local.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/script_options.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/script_options.py new file mode 120000 index 000000000..829ef3af5 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/boundary_layer/script_options.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/boundary_layer/script_options.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/global.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/global.py new file mode 120000 index 000000000..9d9260b1e --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/global.py @@ -0,0 +1 @@ +../../meto-ex1a/transmute/global.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/gravity_wave_drag/gw_ussp_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/gravity_wave_drag/gw_ussp_mod.py new file mode 120000 index 000000000..e666aac63 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/gravity_wave_drag/gw_ussp_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/gravity_wave_drag/gw_ussp_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/bm_tau_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/bm_tau_kernel_mod.py new file mode 120000 index 000000000..d739b20cf --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/bm_tau_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/conv_gr_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/conv_gr_kernel_mod.py new file mode 120000 index 000000000..9eb6a2bd5 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/conv_gr_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/conv_gr_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_exp_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_exp_kernel_mod.py new file mode 120000 index 000000000..6da54cffe --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_exp_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/jules_exp_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_extra_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_extra_kernel_mod.py new file mode 120000 index 000000000..a55a809de --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_extra_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/jules_extra_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_imp_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_imp_kernel_mod.py new file mode 120000 index 000000000..60f768d97 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/jules_imp_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/jules_imp_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/lw_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/lw_kernel_mod.py new file mode 120000 index 000000000..a988c91b2 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/lw_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/lw_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/pc2_conv_coupling_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/pc2_conv_coupling_kernel_mod.py new file mode 120000 index 000000000..859f80221 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/pc2_conv_coupling_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/pc2_initiation_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/pc2_initiation_kernel_mod.py new file mode 120000 index 000000000..83ba30d43 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/pc2_initiation_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/sw_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/sw_kernel_mod.py new file mode 120000 index 000000000..d35f19b05 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/sw_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/sw_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/sw_rad_tile_kernel_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/sw_rad_tile_kernel_mod.py new file mode 120000 index 000000000..6ad26ebf4 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/kernel/sw_rad_tile_kernel_mod.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/kernel/sw_rad_tile_kernel_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_bl_forced_cu.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_bl_forced_cu.py new file mode 120000 index 000000000..31274a37a --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_bl_forced_cu.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/large_scale_cloud/pc2_bl_forced_cu.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_bm_initiate.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_bm_initiate.py new file mode 120000 index 000000000..f1985f0fb --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_bm_initiate.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/large_scale_cloud/pc2_bm_initiate.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_initiation_ctl.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_initiation_ctl.py new file mode 120000 index 000000000..ad930479e --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/large_scale_cloud/pc2_initiation_ctl.py @@ -0,0 +1 @@ +../../../meto-ex1a/transmute/large_scale_cloud/pc2_initiation_ctl.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/control/core/top_level/ukca_main1-ukca_main1.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/control/core/top_level/ukca_main1-ukca_main1.py new file mode 120000 index 000000000..1e508fee4 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/control/core/top_level/ukca_main1-ukca_main1.py @@ -0,0 +1 @@ +../../../../../../../../meto-ex1a/transmute/science/ukca/src/control/core/top_level/ukca_main1-ukca_main1.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/science/core/aerosols/glomap/ukca_aero_ctl.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/science/core/aerosols/glomap/ukca_aero_ctl.py new file mode 120000 index 000000000..842cc90b6 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/science/core/aerosols/glomap/ukca_aero_ctl.py @@ -0,0 +1 @@ +../../../../../../../../../meto-ex1a/transmute/science/ukca/src/science/core/aerosols/glomap/ukca_aero_ctl.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/science/core/chemistry/ukca_chemistry_ctl_full_mod.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/science/core/chemistry/ukca_chemistry_ctl_full_mod.py new file mode 120000 index 000000000..b80baaed8 --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/science/ukca/src/science/core/chemistry/ukca_chemistry_ctl_full_mod.py @@ -0,0 +1 @@ +../../../../../../../../meto-ex1a/transmute/science/ukca/src/science/core/chemistry/ukca_chemistry_ctl_full_mod.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/nci-gadi/transmute/script_options.py b/applications/lfric_atm/optimisation/nci-gadi/transmute/script_options.py new file mode 120000 index 000000000..d887dbe9e --- /dev/null +++ b/applications/lfric_atm/optimisation/nci-gadi/transmute/script_options.py @@ -0,0 +1 @@ +../../meto-ex1a/transmute/script_options.py \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/uoe-dial3 b/applications/lfric_atm/optimisation/uoe-dial3 new file mode 120000 index 000000000..e5b7210c6 --- /dev/null +++ b/applications/lfric_atm/optimisation/uoe-dial3 @@ -0,0 +1 @@ +meto-ex1a \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/uoe-dial3/psykal/global.py b/applications/lfric_atm/optimisation/uoe-dial3/psykal/global.py deleted file mode 100644 index 758965e4e..000000000 --- a/applications/lfric_atm/optimisation/uoe-dial3/psykal/global.py +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################## -# Copyright (c) 2017, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## - - -''' -PSyclone transformation script for the LFRic (Dynamo0p3) API to apply -colouring, OpenMP and redundant computation to the level-1 halo for -the initialisation built-ins generically. - -''' - -from psyclone_tools import (redundant_computation_setval, colour_loops, - openmp_parallelise_loops, - view_transformed_schedule) - - -def trans(psyir): - ''' - Applies PSyclone colouring, OpenMP and redundant computation - transformations. - - :param psyir: the PSyIR of the PSy-layer. - :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` - - ''' - redundant_computation_setval(psyir) - colour_loops(psyir) - openmp_parallelise_loops(psyir) - view_transformed_schedule(psyir) diff --git a/applications/lfric_atm/optimisation/uoe-epic b/applications/lfric_atm/optimisation/uoe-epic new file mode 120000 index 000000000..e5b7210c6 --- /dev/null +++ b/applications/lfric_atm/optimisation/uoe-epic @@ -0,0 +1 @@ +meto-ex1a \ No newline at end of file diff --git a/applications/lfric_atm/optimisation/uoe-epic/psykal/global.py b/applications/lfric_atm/optimisation/uoe-epic/psykal/global.py deleted file mode 100644 index 758965e4e..000000000 --- a/applications/lfric_atm/optimisation/uoe-epic/psykal/global.py +++ /dev/null @@ -1,32 +0,0 @@ -############################################################################## -# Copyright (c) 2017, Met Office, on behalf of HMSO and Queen's Printer -# For further details please refer to the file LICENCE.original which you -# should have received as part of this distribution. -############################################################################## - - -''' -PSyclone transformation script for the LFRic (Dynamo0p3) API to apply -colouring, OpenMP and redundant computation to the level-1 halo for -the initialisation built-ins generically. - -''' - -from psyclone_tools import (redundant_computation_setval, colour_loops, - openmp_parallelise_loops, - view_transformed_schedule) - - -def trans(psyir): - ''' - Applies PSyclone colouring, OpenMP and redundant computation - transformations. - - :param psyir: the PSyIR of the PSy-layer. - :type psyir: :py:class:`psyclone.psyir.nodes.FileContainer` - - ''' - redundant_computation_setval(psyir) - colour_loops(psyir) - openmp_parallelise_loops(psyir) - view_transformed_schedule(psyir) diff --git a/applications/lfric_atm/rose-meta/lfric-lfric_atm/version30_31.py b/applications/lfric_atm/rose-meta/lfric-lfric_atm/version30_31.py new file mode 100644 index 000000000..7c13cb416 --- /dev/null +++ b/applications/lfric_atm/rose-meta/lfric-lfric_atm/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-lfric_atm + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/lfric_atm/rose-meta/lfric-lfric_atm/versions.py b/applications/lfric_atm/rose-meta/lfric-lfric_atm/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/lfric_atm/rose-meta/lfric-lfric_atm/versions.py +++ b/applications/lfric_atm/rose-meta/lfric-lfric_atm/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/lfric_atm/rose-meta/lfric-lfric_atm/vn3.1/rose-meta.conf b/applications/lfric_atm/rose-meta/lfric-lfric_atm/vn3.1/rose-meta.conf new file mode 100644 index 000000000..47acbb91f --- /dev/null +++ b/applications/lfric_atm/rose-meta/lfric-lfric_atm/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-gungho/vn3.1 diff --git a/applications/lfric_atm/source/lfric_atm.f90 b/applications/lfric_atm/source/lfric_atm.f90 index e9b74a91a..e77c16ddb 100644 --- a/applications/lfric_atm/source/lfric_atm.f90 +++ b/applications/lfric_atm/source/lfric_atm.f90 @@ -16,32 +16,37 @@ program lfric_atm - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use driver_collections_mod, only: init_collections, final_collections use driver_comm_mod, only: init_comm, final_comm use driver_config_mod, only: init_config, final_config use driver_counter_mod, only: init_counters, final_counters use driver_log_mod, only: init_logger, final_logger use driver_time_mod, only: init_time, final_time - use driver_timer_mod, only: init_timers, final_timers use gungho_mod, only: gungho_required_namelists use driver_modeldb_mod, only: modeldb_type use gungho_driver_mod, only: initialise, step, finalise use lfric_mpi_mod, only: global_mpi use namelist_mod, only: namelist_type - - use timing_mod, only: init_timing, start_timing, stop_timing, final_timing, tik, LPROF + use timing_mod, only: init_timing, final_timing, & + start_timing, stop_timing, & + tik, LPROF + use io_config_mod, only: timer_output_path implicit none ! Model run working data set type(modeldb_type) :: modeldb - character(*), parameter :: application_name = "lfric_atm" - character(:), allocatable :: filename - integer(tik) :: timing_handle_global + character(*), parameter :: application_name = "lfric_atm" + character(:), allocatable :: filename + integer(tik) :: id_setup type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) + modeldb%mpi => global_mpi call modeldb%configuration%initialise( application_name, & @@ -67,17 +72,17 @@ program lfric_atm call modeldb%io_contexts%initialise(application_name, 100) call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) + call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) - call init_timers( application_name ) io_nml => modeldb%configuration%get_namelist('io') call io_nml%get_value('subroutine_timers', lsubroutine_timers) - call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers ) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, application_name, timer_output_path ) nullify( io_nml ) - if ( LPROF ) call start_timing( timing_handle_global, '__lfric_atm__ ') + if ( LPROF ) call start_timing( id_setup, '__setup__' ) + call init_collections() call init_time( modeldb ) @@ -85,6 +90,7 @@ program lfric_atm deallocate( filename ) call initialise( application_name, modeldb ) + if ( LPROF ) call stop_timing( id_setup, '__setup__' ) do while (modeldb%clock%tick()) call step( modeldb ) end do @@ -93,11 +99,7 @@ program lfric_atm call final_counters( application_name ) call final_time( modeldb ) call final_collections() - - if ( LPROF ) call stop_timing( timing_handle_global ) - call final_timing() - - call final_timers( application_name ) + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/lfric_coupled/Makefile b/applications/lfric_coupled/Makefile index bf65bb5d7..3954e7075 100644 --- a/applications/lfric_coupled/Makefile +++ b/applications/lfric_coupled/Makefile @@ -102,7 +102,7 @@ document-api: api-documentation build: export BIN_DIR ?= $(PROJECT_DIR)/bin build: export CXX_LINK = TRUE build: export PROGRAMS := $(basename $(notdir $(shell find source -maxdepth 1 -name '*.[Ff]90' -print))) -build: export SCRATCH_DIR := $(WORKING_DIR)/../physics_scratch +build: export SCRATCH_DIR := $(WORKING_DIR)/.. build: export PROJECT = $(PROJECT_NAME) build: export WORKING_DIR := $(WORKING_DIR)/$(PROJECT_NAME) @@ -168,10 +168,15 @@ build: ALWAYS PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" + $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute_pass.mk \ + SOURCE_DIR=$(WORKING_DIR) \ + OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute.mk \ SOURCE_DIR=$(WORKING_DIR) \ OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" $(call MESSAGE,========================================) diff --git a/applications/lfric_coupled/build/compile_options.mk b/applications/lfric_coupled/build/compile_options.mk index 10ad895f2..9623d56e1 100644 --- a/applications/lfric_coupled/build/compile_options.mk +++ b/applications/lfric_coupled/build/compile_options.mk @@ -9,7 +9,8 @@ $(info UM physics specific compile options for $(FORTRAN_COMPILER) compiler) include $(PROJECT_DIR)/build/fortran/$(FORTRAN_COMPILER).mk -science/%.o science/%.mod: private FFLAGS_EXTRA += $(FFLAGS_UM_PHYSICS) +casim/%.o science/%.mod: private FFLAGS_EXTRA += $(FFLAGS_UM_PHYSICS) +ukca/%.o science/%.mod: private FFLAGS_EXTRA += $(FFLAGS_UM_PHYSICS) jules/%.o jules/%.mod: private FFLAGS_EXTRA += $(FFLAGS_UM_PHYSICS) socrates/%.o socrates/%.mod: private FFLAGS_EXTRA += $(FFLAGS_UM_PHYSICS) legacy/%.o legacy/%.mod: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) diff --git a/applications/lfric_coupled/build/fortran/crayftn.mk b/applications/lfric_coupled/build/fortran/crayftn.mk index 3f3205685..794ea2c32 100644 --- a/applications/lfric_coupled/build/fortran/crayftn.mk +++ b/applications/lfric_coupled/build/fortran/crayftn.mk @@ -54,8 +54,6 @@ ifeq ($(shell expr ${CRAYFTN_VERSION} \>= 015000000), 1) %driver_modeldb_mod.o %driver_modeldb_mod.mod: private FFLAGS_DEBUG = -G0 %driver_time_mod.o %driver_time_mod.mod: private FFLAGS_SAFE_OPTIMISATION = -O0 %driver_time_mod.o %driver_time_mod.mod: private FFLAGS_DEBUG = -G0 - %driver_timer_mod.o %driver_timer_mod.mod: private FFLAGS_SAFE_OPTIMISATION = -O0 - %driver_timer_mod.o %driver_timer_mod.mod: private FFLAGS_DEBUG = -G0 %io_context_collection_mod.o %io_context_collection_mod.mod: private FFLAGS_SAFE_OPTIMISATION = -O0 %io_context_collection_mod.o %io_context_collection_mod.mod: private FFLAGS_DEBUG = -G0 %variable_fields_mod.o %variable_fields_mod.mod: private FFLAGS_SAFE_OPTIMISATION = -O0 diff --git a/applications/lfric_coupled/build/psyclone_transmute_file_list.mk b/applications/lfric_coupled/build/psyclone_transmute_file_list.mk index d216272da..77dc6fade 100644 --- a/applications/lfric_coupled/build/psyclone_transmute_file_list.mk +++ b/applications/lfric_coupled/build/psyclone_transmute_file_list.mk @@ -18,6 +18,11 @@ export PSYCLONE_PHYSICS_FILES = ##### TRANSMUTE_INCLUDE_METHOD specify_include ##### +# List to use PSyclone explicitly without any opt script +# This will remove hand written (OMP) directives in the source +# Used by both methods, specify_include and specify_exclude +export PSYCLONE_PASS_NO_SCRIPT = + ##### TRANSMUTE_INCLUDE_METHOD specify_exclude ##### # For GPU, we may want to use more generic local.py transformation scripts and psyclone by directory. # Advise which directories to pass to PSyclone. diff --git a/applications/lfric_coupled/example/configuration.nml b/applications/lfric_coupled/example/configuration.nml index 643f92211..e160a8be8 100644 --- a/applications/lfric_coupled/example/configuration.nml +++ b/applications/lfric_coupled/example/configuration.nml @@ -168,6 +168,9 @@ write_minmax_tseries=.false., l_hydrology=.true., l_var_rainfrac=.false. / +&jules_model_environment_lfric +l_jules_parent='lfric', +/ &jules_nvegparm albsnc_nvg_io=0.4,0.8,0.8,0.8, albsnf_nvg_io=0.18,0.12,-1.0,0.75, @@ -239,12 +242,29 @@ l_soil_sat_down=.true., l_vg_soil=.true. / &jules_surface +all_tiles='off', +beta1=0.83, +beta2=0.93, cor_mo_iter='lim_oblen', fd_stability_dep='none', formdrag='eff_z0', +fwe_c3=0.5, +fwe_c4=20000.0, +hleaf=5.7e4, +hwood=1.1e4, +i_modiscopt='on', +iscrntdiag='decoupled_trans', l_anthrop_heat_src=.false., +l_epot_corr=.true., +l_elev_land_ice=.false., +l_elev_lw_down=.false., +l_flake_model=.false., +l_land_ice_imp=.true., +l_mo_buoyancy_calc=.true., +l_point_data=.false., l_urban2t=.false., -l_vary_z0m_soil=.false. +l_vary_z0m_soil=.false., +orog_drag_param=0.15, srf_ex_cnv_gust=.true., / &jules_surface_types @@ -388,6 +408,7 @@ tau_u=0.55, &transport adjust_theta=.false. adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj='upwind' diff --git a/applications/lfric_coupled/example/iodef.xml b/applications/lfric_coupled/example/iodef.xml index e8e6859ca..e84891cc3 100644 --- a/applications/lfric_coupled/example/iodef.xml +++ b/applications/lfric_coupled/example/iodef.xml @@ -486,7 +486,7 @@ performance - 1.0 + 1.0 diff --git a/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/version30_31.py b/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/version30_31.py new file mode 100644 index 000000000..d43e7f54c --- /dev/null +++ b/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-lfric_coupled + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/versions.py b/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/versions.py +++ b/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/vn3.1/rose-meta.conf b/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/vn3.1/rose-meta.conf new file mode 100644 index 000000000..47acbb91f --- /dev/null +++ b/applications/lfric_coupled/rose-meta/lfric-lfric_coupled/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-gungho/vn3.1 diff --git a/applications/lfric_coupled/source/lfric_coupled.f90 b/applications/lfric_coupled/source/lfric_coupled.f90 index 6efc6bf31..2f22b8bc0 100644 --- a/applications/lfric_coupled/source/lfric_coupled.f90 +++ b/applications/lfric_coupled/source/lfric_coupled.f90 @@ -16,7 +16,7 @@ program lfric_coupled - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use coupler_mod, only : set_cpl_name use driver_collections_mod, only : init_collections, final_collections use driver_comm_mod, only : init_comm, final_comm @@ -27,16 +27,22 @@ program lfric_coupled use gungho_driver_mod, only : initialise, step, finalise use driver_modeldb_mod, only : modeldb_type use lfric_mpi_mod, only : global_mpi + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path implicit none ! Model run working data set type(modeldb_type) :: modeldb - character(*), parameter :: application_name = "lfric_coupled" - character(*), parameter :: cpl_component_name = "lfric" + character(*), parameter :: application_name = "lfric_coupled" + character(*), parameter :: cpl_component_name = "lfric" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers - character(:), allocatable :: filename + call parse_command_line( filename ) modeldb%mpi => global_mpi @@ -63,10 +69,14 @@ program lfric_coupled call set_cpl_name(modeldb, cpl_component_name) call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) + call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, application_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) deallocate(filename) @@ -79,6 +89,7 @@ program lfric_coupled call final_time( modeldb ) call final_collections() + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/lfricinputs/source/common/lfricinp_lfric_driver_mod.f90 b/applications/lfricinputs/source/common/lfricinp_lfric_driver_mod.f90 index a0630d7bf..cd39b0b27 100644 --- a/applications/lfricinputs/source/common/lfricinp_lfric_driver_mod.f90 +++ b/applications/lfricinputs/source/common/lfricinp_lfric_driver_mod.f90 @@ -132,7 +132,7 @@ subroutine lfricinp_initialise_lfric(program_name_arg, & character(str_def) :: prime_mesh_name -integer(i_def) :: stencil_depth +integer(i_def) :: stencil_depth(1) integer(i_def) :: geometry real(r_def) :: domain_bottom real(r_def) :: scaled_radius diff --git a/applications/linear_model/example/configuration.nml b/applications/linear_model/example/configuration.nml index 5ed21fc6c..6c85616bc 100644 --- a/applications/linear_model/example/configuration.nml +++ b/applications/linear_model/example/configuration.nml @@ -154,6 +154,7 @@ write_minmax_tseries=.false., fixed_ls=.false. pert_option='analytic', l_stabilise_bl=.false., +transport_efficiency=.false., / &logging run_log_level='info', @@ -226,6 +227,7 @@ spinup_alpha=.false., &transport adjust_theta=.false. adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj = 'upwind', @@ -262,11 +264,11 @@ panel_edge_high_order=.true., panel_edge_treatment='none' reversible=.false.,.false.,.false.,.false.,.false. runge_kutta_method='ssp3' -scheme=1,1,1,1,1 +scheme=5*3 si_outer_transport='none', slice_order='parabola' special_edges_monotone=5*1 -splitting=1,1,1,1,1 +splitting=5*2 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' diff --git a/applications/linear_model/example/iodef.xml b/applications/linear_model/example/iodef.xml index 65df40e15..e00c7e843 100644 --- a/applications/linear_model/example/iodef.xml +++ b/applications/linear_model/example/iodef.xml @@ -80,9 +80,9 @@ - - - + + + @@ -134,6 +134,8 @@ + + @@ -180,6 +182,8 @@ + + @@ -371,7 +375,7 @@ performance - 1.0 + 1.0 diff --git a/applications/linear_model/example_file/config_linear.nml b/applications/linear_model/example_file/config_linear.nml index 18df08580..301120422 100644 --- a/applications/linear_model/example_file/config_linear.nml +++ b/applications/linear_model/example_file/config_linear.nml @@ -222,6 +222,7 @@ spinup_alpha=.false., &transport adjust_theta=.false. adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj = 'upwind', diff --git a/applications/linear_model/example_file/config_nonlinear.nml b/applications/linear_model/example_file/config_nonlinear.nml index b32d3f15b..e14b9d6bb 100644 --- a/applications/linear_model/example_file/config_nonlinear.nml +++ b/applications/linear_model/example_file/config_nonlinear.nml @@ -216,6 +216,7 @@ spinup_alpha=.false., &transport adjust_theta=.false. adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj = 'upwind' diff --git a/applications/linear_model/example_file/iodef.xml b/applications/linear_model/example_file/iodef.xml index 4bfa9b3c2..f8232d261 100644 --- a/applications/linear_model/example_file/iodef.xml +++ b/applications/linear_model/example_file/iodef.xml @@ -360,7 +360,7 @@ performance - 1.0 + 1.0 diff --git a/applications/linear_model/plot_convergence/plot_convergence.sh b/applications/linear_model/plot_convergence/plot_convergence.sh deleted file mode 100755 index ab6e366a5..000000000 --- a/applications/linear_model/plot_convergence/plot_convergence.sh +++ /dev/null @@ -1,83 +0,0 @@ -############################################################################## -# (c) Crown copyright 2022 Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -############################################################################## - -#---------------------------------------------------------------------- -# Plots the convergence rate of the tangent linear model. -#---------------------------------------------------------------------- - -# INSTRUCTIONS TO RUN -# 1. Specify CONFIG -# 2. Run using . plot_convergence.sh, from the plot_convergence directory - -# SCIENCE DETAILS -# The relative linearisation error is -# E = || N(x+ gamma x') - N(x) - L(x) gamma x' || / || L(x) gamma x' || -# where N=nonlinear model, L=linear model, x=linearisation state -# x'=perturbation, gamma=scalar. -# From the Taylor series expansion, E(gamma) = O(gamma) i.e. of the order gamma -# So the relative error should be a linear function of gamma - -# SCRIPT STEPS -# 1. Produce the data: The integration test tl_test_timesteps is extended by -# running over 10 values of gamma, rather than 2 values of gamma. -# 2. Plot the data: The data is plotted for each prognostic variable. - -# EXTENSION -# The plot_configuration.nml can also be extended to other configurations e.g -# * increase the number of timesteps (timesteps_end) -# * increase the number of timesteps between updating the linearisation state -# (update_ls_frequency) - -#-------------------------------------------------------------------------- - -# CONFIG can be specified as either runge_kutta or semi_implicit -CONFIG=semi_implicit - -# Define directories using the current working directory -Working_dir=$PWD -Linear_dir="$(dirname "$PWD")" - -# Integration tests executable name -exe=$Linear_dir/test/$CONFIG - -# Build the integration tests, unless that has already been completed -if [ -f $exe ] ; then - echo "Do not need to build the executable as $exe exists" -else - echo "$exe does not exist, so now building the executable" - cd $Linear_dir - make integration-tests - - if [$? -ne 0 ]; then - echo "Error building the executable" - return - fi -fi - -# Setup the configuration - to test with 10 values of gamma -cd $Linear_dir/test/test_files/$CONFIG -cp ${CONFIG}_configuration.nml plot_configuration.nml -sed -i 's/number_gamma_values=2/number_gamma_values=10/g' plot_configuration.nml -if [ $? -ne 0 ]; then - echo "Error in creating plot_configuration.nml" - return -fi - -# Run the tl_test_timesteps integration test -echo "Running the integration test" -../../$CONFIG plot_configuration.nml test_timesteps > outfile -if [ $? -ne 0 ]; then - echo "Error in creating outfile data" - return -else - echo "Data created successfully" -fi - -# Plot the data, together with the expected gradient -echo "Plotting the data" -python $Working_dir/plot_convergence.py - - diff --git a/applications/linear_model/rose-meta/lfric-linear_model/version30_31.py b/applications/linear_model/rose-meta/lfric-linear_model/version30_31.py new file mode 100644 index 000000000..f999b676e --- /dev/null +++ b/applications/linear_model/rose-meta/lfric-linear_model/version30_31.py @@ -0,0 +1,282 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear_model + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/linear_model/rose-meta/lfric-linear_model/versions.py b/applications/linear_model/rose-meta/lfric-linear_model/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/linear_model/rose-meta/lfric-linear_model/versions.py +++ b/applications/linear_model/rose-meta/lfric-linear_model/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/linear_model/rose-meta/lfric-linear_model/vn3.1/rose-meta.conf b/applications/linear_model/rose-meta/lfric-linear_model/vn3.1/rose-meta.conf new file mode 100644 index 000000000..a95b2cf2e --- /dev/null +++ b/applications/linear_model/rose-meta/lfric-linear_model/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-linear/vn3.1 diff --git a/applications/linear_model/source/linear_model.f90 b/applications/linear_model/source/linear_model.f90 index a8d448b35..8ba21132b 100644 --- a/applications/linear_model/source/linear_model.f90 +++ b/applications/linear_model/source/linear_model.f90 @@ -14,13 +14,12 @@ program linear_model - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use driver_collections_mod, only : init_collections, final_collections use driver_comm_mod, only : init_comm, final_comm use driver_config_mod, only : init_config, final_config use driver_log_mod, only : init_logger, final_logger use driver_time_mod, only : init_time, final_time - use driver_timer_mod, only : init_timers, final_timers use gungho_mod, only : gungho_required_namelists use driver_modeldb_mod, only : modeldb_type use lfric_mpi_mod, only : global_mpi @@ -28,14 +27,21 @@ program linear_model use log_mod, only : log_event, & log_level_trace, & log_scratch_space + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path implicit none ! Model run working data set type (modeldb_type) :: modeldb - character(*), parameter :: application_name = "linear_model" - character(:), allocatable :: filename + character(*), parameter :: application_name = "linear_model" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) modeldb%mpi => global_mpi @@ -59,11 +65,14 @@ program linear_model call modeldb%io_contexts%initialise(application_name, 100) call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) + call init_config( filename, gungho_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), application_name ) - call init_timers( application_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, application_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) deallocate( filename ) @@ -81,7 +90,7 @@ program linear_model call final_time( modeldb ) call final_collections() - call final_timers( application_name ) + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/name_transport/example/configuration.nml b/applications/name_transport/example/configuration.nml index 3bcb4b2f4..daaa66420 100644 --- a/applications/name_transport/example/configuration.nml +++ b/applications/name_transport/example/configuration.nml @@ -129,6 +129,7 @@ runge_kutta_method='forward_euler', &transport adjust_theta=.false. adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj='upwind' diff --git a/applications/name_transport/example/iodef.xml b/applications/name_transport/example/iodef.xml index 41eacd45f..aebf8ba46 100644 --- a/applications/name_transport/example/iodef.xml +++ b/applications/name_transport/example/iodef.xml @@ -107,7 +107,7 @@ performance - 1.0 + 1.0 diff --git a/applications/name_transport/optimisation/niwa-xc50/psykal/global.py b/applications/name_transport/optimisation/niwa-xc50/psykal/global.py index 02c220077..8437ff20e 120000 --- a/applications/name_transport/optimisation/niwa-xc50/psykal/global.py +++ b/applications/name_transport/optimisation/niwa-xc50/psykal/global.py @@ -1 +1 @@ -./../../meto-xc40/psykal/global.py \ No newline at end of file +../../../../../applications/name_transport/optimisation/meto-ex1a/psykal/global.py \ No newline at end of file diff --git a/applications/name_transport/rose-meta/lfric-name_transport/version30_31.py b/applications/name_transport/rose-meta/lfric-name_transport/version30_31.py new file mode 100644 index 000000000..f3ae24ff5 --- /dev/null +++ b/applications/name_transport/rose-meta/lfric-name_transport/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-name_transport + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/name_transport/rose-meta/lfric-name_transport/versions.py b/applications/name_transport/rose-meta/lfric-name_transport/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/name_transport/rose-meta/lfric-name_transport/versions.py +++ b/applications/name_transport/rose-meta/lfric-name_transport/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/name_transport/rose-meta/lfric-name_transport/vn3.1/rose-meta.conf b/applications/name_transport/rose-meta/lfric-name_transport/vn3.1/rose-meta.conf new file mode 100644 index 000000000..6c7ece3c7 --- /dev/null +++ b/applications/name_transport/rose-meta/lfric-name_transport/vn3.1/rose-meta.conf @@ -0,0 +1,145 @@ +import=lfric-gungho/vn3.1 + +#============================================================================== +# INITIAL NAME FIELD +#============================================================================== +[namelist:initial_name_field] +compulsory=true +description=Namelist options to set up the tracer fields in the name_transport miniapp. +help=?????? + =?????? +!kind=default +ns=namelist/Job/Initial conditions/Tracer +sort-key=Section-A03 + +[namelist:initial_name_field=field_background] +compulsory=true +description=Background value of the tracer field. +fail-if=this < 0.0 ; +help=Background value of tracer. The tracer value away from the + =set tracer function, usually the minimum tracer value. +!kind=default +range=0.0: +sort-key=Panel-A03 +type=real + +[namelist:initial_name_field=field_max] +compulsory=true +description=Maximum value of tracer field function. +fail-if=this < 0.0 ; +help=The maximum value of the tracer field function. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[namelist:initial_name_field=r1] +compulsory=true +description=Radius of initial tracer field function. +fail-if=this < 0.0 ; +help=Radius for one of the pair of initial tracer field functions + =Biperiodic domain: in metres. + =Cubed sphere domain: in radians. +!kind=default +range=0.0: +sort-key=Panel-A04 +type=real + +[namelist:initial_name_field=r2] +compulsory=true +description=Radius of second initial tracer field function. +fail-if= +help=Radius parameter for the second of the pair of initial tracer field functions (see r1) +!kind=default +!range= +sort-key=Panel-A08 +trigger= +type=real + +[namelist:initial_name_field=x1] +compulsory=true +description=Centre in long/x of tracer field function. +help=Position for one of the pair of initial tracer field functions + =Biperiodic domain: centre of the function given in terms of metres in the chi1 direction. + =Cubed sphere domain: longitudinal position of the centre of the function (a value between 0 and \f$2\pi\f$). +!kind=default +sort-key=Panel-A05 +trigger= +type=real + +[namelist:initial_name_field=x2] +compulsory=true +description=Centre in long/x of second tracer field function. +fail-if= +help=Position parameter for the second of the pair of initial tracer field functions (see x1) +!kind=default +!range= +sort-key=Panel-A09 +trigger= +type=real + +[namelist:initial_name_field=y1] +compulsory=true +description=Centre in lat/y of tracer field function. +fail-if= +help=Position for one of the pair of initial tracer field functions + =Biperiodic domain: centre of the function given in terms of metres in the chi2 direction. + =Cubed sphere domain: latitudinal position of the centre of the function (a value between \f$-\pi/2\f$ and \f$\pi/2\f$). +!kind=default +!range= +sort-key=Panel-A06 +trigger= +type=real + +[namelist:initial_name_field=y2] +compulsory=true +description=Centre in lat/y of second tracer field function. +fail-if= +help=Position parameter for the second of the pair of initial tracer field functions (see y1) +!kind=default +!range= +sort-key=Panel-A10 +trigger= +type=real + +[namelist:initial_name_field=z1] +compulsory=true +description=Centre in height of tracer field function. +fail-if= +help=Centre height position for one of the pair of initial tracer field functions +!kind=default +!range= +sort-key=Panel-A07 +trigger= +type=real + +[namelist:initial_name_field=z2] +compulsory=true +description=Centre in height of second tracer field function. +fail-if= +help=Centre height position for one of the pair of initial tracer field functions +!kind=default +!range= +sort-key=Panel-A11 +trigger= +type=real + +[namelist:name_options] +compulsory=true +description=Namelist options for the NAME transport miniapp. +help=Specific options for the NAME transport miniapp to ensure the correct + =things are transported by the correct winds. +!kind=default +ns=namelist/Science/Dynamics/Transport/Name +sort-key=Section-A01 + +[namelist:name_options=transport_density] +compulsory=true +description=Whether to transport density within the NAME application. +fail-if= +help=If set to true the density will be transported. If set to false the + =density must be read in and passed to the application at each + =time step. +!kind=default +sort-key=Panel-A02 +type=logical diff --git a/applications/name_transport/source/driver/name_transport_driver_mod.f90 b/applications/name_transport/source/driver/name_transport_driver_mod.f90 index 94e8365c0..c0ef0ec06 100644 --- a/applications/name_transport/source/driver/name_transport_driver_mod.f90 +++ b/applications/name_transport/source/driver/name_transport_driver_mod.f90 @@ -45,7 +45,8 @@ module name_transport_driver_mod use sci_geometric_constants_mod, only: get_chi_inventory, & get_panel_id_inventory, & get_height_fe - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Transport algorithms use name_transport_init_fields_alg_mod, only: name_transport_init_fields_alg @@ -108,12 +109,12 @@ subroutine initialise_name_transport( program_name, modeldb ) character(len=str_def), allocatable :: shifted_names(:) character(len=str_def), allocatable :: double_names(:) character(len=str_def) :: prime_mesh_name + integer(kind=i_def), allocatable :: stencil_depths(:) logical(kind=l_def) :: prepartitioned logical(kind=l_def) :: apply_partition_check integer(kind=i_def) :: geometry - integer(kind=i_def) :: stencil_depth real(kind=r_def) :: domain_bottom real(kind=r_def) :: domain_height real(kind=r_def) :: scaled_radius @@ -236,14 +237,18 @@ subroutine initialise_name_transport( program_name, modeldb ) ! 1.3a Initialise prime/2d meshes ! --------------------------------------------------------- - stencil_depth = get_required_stencil_depth() + allocate(stencil_depths(num_base_meshes)) + call get_required_stencil_depth( & + stencil_depths, base_mesh_names, modeldb%configuration & + ) + apply_partition_check = .false. call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & base_mesh_names, & - extrusion, stencil_depth, & + extrusion, stencil_depths, & apply_partition_check ) call create_mesh( base_mesh_names, extrusion_2d, & @@ -350,11 +355,19 @@ subroutine initialise_name_transport( program_name, modeldb ) end if - if (allocated(base_mesh_names)) deallocate(base_mesh_names) - if (allocated(meshes_to_shift)) deallocate(meshes_to_shift) - if (allocated(meshes_to_double)) deallocate(meshes_to_double) - + if (allocated(base_mesh_names)) deallocate(base_mesh_names) + if (allocated(meshes_to_shift)) deallocate(meshes_to_shift) + if (allocated(meshes_to_double)) deallocate(meshes_to_double) + if (allocated(twod_names)) deallocate(twod_names) + if (allocated(shifted_names)) deallocate(shifted_names) + if (allocated(double_names)) deallocate(double_names) + if (allocated(extrusion)) deallocate(extrusion) + if (allocated(extrusion_2d)) deallocate(extrusion_2d) + if (allocated(extrusion_shifted)) deallocate(extrusion_shifted) + if (allocated(extrusion_double)) deallocate(extrusion_double) + if (allocated(stencil_depths)) deallocate(stencil_depths) if (allocated(extra_io_mesh_names)) deallocate(extra_io_mesh_names) + nullify(chi_inventory, panel_id_inventory, mesh) end subroutine initialise_name_transport @@ -367,7 +380,6 @@ subroutine step_name_transport( model_clock ) use base_mesh_config_mod, only: prime_mesh_name use io_config_mod, only: diagnostic_frequency, & nodal_output_on_w3, & - subroutine_timers, & write_diag use sci_field_minmax_alg_mod, only: log_field_minmax @@ -376,6 +388,7 @@ subroutine step_name_transport( model_clock ) class(model_clock_type), intent(in) :: model_clock type(mesh_type), pointer :: mesh + integer(tik) :: id ! Get mesh mesh => mesh_collection%get_mesh(prime_mesh_name) @@ -392,13 +405,13 @@ subroutine step_name_transport( model_clock ) 'Start of timestep ', model_clock%get_step() call log_event( log_scratch_space, LOG_LEVEL_INFO ) - if ( subroutine_timers ) call timer( 'name transport step' ) + if ( LPROF ) call start_timing( id, 'name_transport_step' ) ! Transport field call name_transport_step( model_clock, wind, tracer_con, & density, transport_density ) - if ( subroutine_timers ) call timer( 'name transport step' ) + if ( LPROF ) call stop_timing( id, 'name_transport_step' ) ! Print min/max of fields after transport step if (transport_density) then diff --git a/applications/name_transport/source/kernel/set_name_field_kernel_mod.F90 b/applications/name_transport/source/kernel/set_name_field_kernel_mod.F90 index b0a58ca5c..453a1cc18 100644 --- a/applications/name_transport/source/kernel/set_name_field_kernel_mod.F90 +++ b/applications/name_transport/source/kernel/set_name_field_kernel_mod.F90 @@ -21,6 +21,10 @@ module set_name_field_kernel_mod use kernel_mod, only : kernel_type use log_mod, only : log_event, LOG_LEVEL_ERROR + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -143,7 +147,9 @@ subroutine set_name_field_code(nlayers, tracer, & chi_2_e(df1) = chi_2( map_chi(df1) + k ) chi_3_e(df1) = chi_3( map_chi(df1) + k ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, & jac, dj) diff --git a/applications/name_transport/source/name_transport.f90 b/applications/name_transport/source/name_transport.f90 index d6b22502a..c7e5343e4 100644 --- a/applications/name_transport/source/name_transport.f90 +++ b/applications/name_transport/source/name_transport.f90 @@ -9,7 +9,7 @@ program name_transport - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use constants_mod, only: i_def, r_def use driver_collections_mod, only: init_collections, final_collections use driver_comm_mod, only: init_comm, final_comm @@ -17,7 +17,6 @@ program name_transport use driver_log_mod, only: init_logger, final_logger use driver_modeldb_mod, only: modeldb_type use driver_time_mod, only: init_time, final_time - use driver_timer_mod, only: init_timers, final_timers use lfric_mpi_mod, only: global_mpi use log_mod, only: log_event, & log_level_debug, & @@ -30,17 +29,22 @@ program name_transport use name_transport_driver_mod, only: initialise_name_transport, & step_name_transport, & finalise_name_transport - + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path implicit none type(modeldb_type) :: modeldb character(*), parameter :: program_name = "name_transport" character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) call modeldb%configuration%initialise( program_name, table_len=10 ) modeldb%mpi => global_mpi call init_comm( program_name, modeldb ) - call get_initial_filename( filename ) call init_config( filename, name_transport_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), program_name ) @@ -52,7 +56,10 @@ program name_transport write(log_scratch_space, '(" i_def kind = ", I0)') kind(1_i_def) call log_event( log_scratch_space , log_level_info ) - call init_timers( program_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, program_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) deallocate( filename ) @@ -74,7 +81,7 @@ program name_transport call final_time( modeldb ) call final_collections() - call final_timers( program_name ) + call final_timing( program_name ) call final_logger( program_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/name_transport/unit-test/kernel/set_name_field_kernel_mod_test.pf b/applications/name_transport/unit-test/kernel/set_name_field_kernel_mod_test.pf index 7ae24e5d4..554823758 100644 --- a/applications/name_transport/unit-test/kernel/set_name_field_kernel_mod_test.pf +++ b/applications/name_transport/unit-test/kernel/set_name_field_kernel_mod_test.pf @@ -91,7 +91,7 @@ contains p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/applications/ngarch/Makefile b/applications/ngarch/Makefile index 9fa685560..a645cd3d2 100644 --- a/applications/ngarch/Makefile +++ b/applications/ngarch/Makefile @@ -100,7 +100,7 @@ document-api: api-documentation build: export BIN_DIR ?= $(PROJECT_DIR)/bin build: export CXX_LINK = TRUE build: export PROGRAMS := $(basename $(notdir $(shell find source -maxdepth 1 -name '*.[Ff]90' -print))) -build: export SCRATCH_DIR := $(WORKING_DIR)/../physics_scratch +build: export SCRATCH_DIR := $(WORKING_DIR)/.. build: export PROJECT = $(PROJECT_NAME) build: export WORKING_DIR := $(WORKING_DIR) @@ -160,10 +160,15 @@ build: ALWAYS PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" + $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute_pass.mk \ + SOURCE_DIR=$(WORKING_DIR) \ + OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" $Q$(MAKE) $(QUIET_ARG) -f $(APPS_ROOT_DIR)/interfaces/physics_schemes_interface/build/psyclone_transmute.mk \ SOURCE_DIR=$(WORKING_DIR) \ OPTIMISATION_PATH_PSY=$(APPS_ROOT_DIR)/applications/$(PROJECT)/$(OPTIMISATION_PATH) \ PSYCLONE_PHYSICS_FILES="$(PSYCLONE_PHYSICS_FILES)" \ + PSYCLONE_PASS_NO_SCRIPT="$(PSYCLONE_PASS_NO_SCRIPT)" \ PSYCLONE_DIRECTORIES="$(PSYCLONE_DIRECTORIES)" \ PSYCLONE_PHYSICS_EXCEPTION="$(PSYCLONE_PHYSICS_EXCEPTION)" $(call MESSAGE,========================================) diff --git a/applications/ngarch/build/compile_options.mk b/applications/ngarch/build/compile_options.mk index 810698d65..4ef9b69bd 100644 --- a/applications/ngarch/build/compile_options.mk +++ b/applications/ngarch/build/compile_options.mk @@ -13,7 +13,8 @@ $(info UM physics specific compile options) include $(PROJECT_DIR)/build/fortran/$(FORTRAN_COMPILER).mk -science/%.o science/%.mod: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) +casim/%.o science/%.mod: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) +ukca/%.o science/%.mod: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) jules/%.o jules/%.mod: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) socrates/%.o socrates/%.mod: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) legacy/%.o legacy/%.mod: private FFLAGS_EXTRA = $(FFLAGS_UM_PHYSICS) diff --git a/applications/ngarch/build/psyclone_transmute_file_list.mk b/applications/ngarch/build/psyclone_transmute_file_list.mk index aaf70e8f2..855979f30 100644 --- a/applications/ngarch/build/psyclone_transmute_file_list.mk +++ b/applications/ngarch/build/psyclone_transmute_file_list.mk @@ -14,13 +14,44 @@ # Choose which files to Pre-proccess and PSyclone from physics / FCM UM source. -export PSYCLONE_PHYSICS_FILES = gw_ussp_mod \ +export PSYCLONE_PHYSICS_FILES = \ + bl_lsp \ + bl_diags_mod \ bm_tau_kernel_mod \ + btq_int \ + conv_gr_kernel_mod \ + ex_flux_tq \ + ex_flux_uv \ + fm_drag \ + gw_ussp_mod \ + imp_mix \ + jules_exp_kernel_mod \ + jules_extra_kernel_mod \ + jules_imp_kernel_mod \ + kmkh \ + kmkhz_9c_wtrac \ + lw_kernel_mod \ + mphys_kernel_mod \ + pc2_initiation_kernel_mod \ + pc2_bl_forced_cu \ + pc2_bm_initiate \ + pc2_initiation_ctl \ pc2_conv_coupling_kernel_mod \ - pc2_initiation_kernel_mod + sw_kernel_mod \ + sw_rad_tile_kernel_mod \ + tr_mix \ + ukca_aero_ctl \ + ukca_chemistry_ctl_full_mod \ + ukca_main1-ukca_main1 + ##### TRANSMUTE_INCLUDE_METHOD specify_include ##### +# List to use PSyclone explicitly without any opt script +# This will remove hand written (OMP) directives in the source +# Used by both methods, specify_include and specify_exclude +export PSYCLONE_PASS_NO_SCRIPT = ukca_abdulrazzak_ghan + ##### TRANSMUTE_INCLUDE_METHOD specify_exclude ##### # For GPU, we may want to use more generic local.py transformation scripts and psyclone by directory. # Advise which directories to pass to PSyclone. diff --git a/applications/ngarch/example/configuration_bl.nml b/applications/ngarch/example/configuration_bl.nml index 87c3e5318..22e22b87f 100644 --- a/applications/ngarch/example/configuration_bl.nml +++ b/applications/ngarch/example/configuration_bl.nml @@ -483,6 +483,7 @@ tau_u=0.55, &transport adjust_theta=.true., adjust_theta_above=30000.0, +adjust_tracer_equation=.false. adjust_vhv_wind=.true., ageofair_reset_level=10, broken_w2_projection=.false., diff --git a/applications/ngarch/example/configuration_casim.nml b/applications/ngarch/example/configuration_casim.nml index 4db857e52..fedbde276 100644 --- a/applications/ngarch/example/configuration_casim.nml +++ b/applications/ngarch/example/configuration_casim.nml @@ -543,6 +543,7 @@ tau_u=0.55, &transport adjust_theta=.true., adjust_theta_above=30000.0, +adjust_tracer_equation=.false. adjust_vhv_wind=.true., ageofair_reset_level=10, broken_w2_projection=.false., diff --git a/applications/ngarch/example/iodef.xml b/applications/ngarch/example/iodef.xml index 48ffab882..b0827d902 100644 --- a/applications/ngarch/example/iodef.xml +++ b/applications/ngarch/example/iodef.xml @@ -96,7 +96,7 @@ performance - 1.0 + 1.0 diff --git a/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bl_forced_cu.py b/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bl_forced_cu.py new file mode 100644 index 000000000..b34a512f6 --- /dev/null +++ b/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bl_forced_cu.py @@ -0,0 +1,47 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to target loops over index i instead of +index j. Trip count of j loops is 1 in LFRic, which prevents parallel +execution. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + get_outer_loops, + get_compiler, + first_priv_red_init, + OMP_PARALLEL_LOOP_DO_TRANS_DYNAMIC, + OMP_PARALLEL_LOOP_DO_TRANS_STATIC +) + + +def trans(psyir): + """ + Apply OpenMP Directives + """ + + # Identify outer loops + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + # Apply OpenMP parallel do directives and use workaround for + # firstprivate variable issue; replicate dynamic and static + # schedules of the original implementation + try: + for idx, loop in enumerate(outer_loops): + if get_compiler() == 'cce': + first_priv_red_init(loop, ["cf_base", "cf_forced", "dcfl", + "dqcl", "qcl_forced", "qcl_tol"]) + if idx == 0: + OMP_PARALLEL_LOOP_DO_TRANS_DYNAMIC.apply(loop.walk(Loop)[1]) + else: + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop.walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bm_initiate.py b/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bm_initiate.py new file mode 100644 index 000000000..b1286eb05 --- /dev/null +++ b/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_bm_initiate.py @@ -0,0 +1,145 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to target loops over index i instead of +index j. Trip count of j loops is 1 in LFRic, which prevents parallel +execution. Private variables need to be declared explicitly as PSyclone +analysis currently misses a scalar variable that a subroutine modifies in +a parallel region. PSyclone thread safety checks need to be overridden; +the subroutines can be safely parallelised. Compiler directives used in +the original code are re-inserted for performance and consistency of output. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import (Loop, CodeBlock) +from transmute_psytrans.transmute_functions import ( + set_pure_subroutines, + get_outer_loops, + mark_explicit_privates, + get_compiler, + first_priv_red_init, + match_lhs_assignments, + match_call_args, + OMP_PARALLEL_REGION_TRANS, + OMP_DO_LOOP_TRANS_STATIC +) + +# Variables in parallel region that need to be private +private_variables = [ + "alphal", "alx", "i", "j", "k", "km1", "kp1", "mux", "tmp", + "frac_init", "kk", "kkm1", "kkp1", "qc", "qc_points", "qsl", + "tlx", "qsi", "idx", "deltacl_c", "deltacf_c", "deltaql_c", + "cf_c", "cfl_c", "cff_c" +] + +# Subroutines that need to be declared as "pure" +pure_subroutines = ["qsat", "qsat_mix", "qsat_wat", "qsat_wat_mix"] + +# Variables that appear on the left-hand side of assignments +# or as call arguments for which PSyclone dependency errors +# can be ignored +false_dep_vars = [ + "qc_points", + "idx", + "tl_in", + "p_theta_levels", + "qsi_lay", + "qsl_lay", +] + + +class CompilerDirective(): + """ + Custom compiler directive class to avoid an issue + with fparser.two.Fortran2003.Directive that will + be resolved in an upcoming fparser release. + """ + def __init__(self, directive): + self.directive = directive + + def tofortran(self): + """ + Return directive with prefix + """ + return "!DIR$ " + self.directive + + +def trans(psyir): + """ + Apply OpenMP and Compiler Directives + """ + + # Declare subroutines as pure to enable parallelisation + # of the encompassing loops + set_pure_subroutines(psyir, pure_subroutines) + + # Identify outer loops for setting up parallel regions + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + # Check if first OpenMP region can be parallelised and + # apply directives + try: + OMP_PARALLEL_REGION_TRANS.validate(outer_loops[0:2]) + OMP_PARALLEL_REGION_TRANS.apply(outer_loops[0:2]) + OMP_DO_LOOP_TRANS_STATIC.apply(outer_loops[0]) + OMP_DO_LOOP_TRANS_STATIC.apply(outer_loops[1].walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("Parallelisation of the 1st region failed: %s", err) + + # Declare private symbols for the last loop nest explicitly, + # PSyclone misses one + mark_explicit_privates(outer_loops[2], private_variables) + + # Parallelise the second region and insert compiler directives + # Add redundant variable initialisation to work around a known + # PSyclone issue when using CCE + try: + if get_compiler() == 'cce': + first_priv_red_init(outer_loops[2], ["i", "j", "k"]) + + OMP_PARALLEL_REGION_TRANS.validate(outer_loops[2:3]) + OMP_PARALLEL_REGION_TRANS.apply(outer_loops[2]) + + # Insert before OpenMP directives to avoid PSyclone errors + if get_compiler() == "cce": + for loop in outer_loops[2].walk(Loop)[3:5]: + cblock = CodeBlock([CompilerDirective("NOFISSION")], + CodeBlock.Structure.STATEMENT) + insert_at = loop.parent.children.index(loop) + loop.parent.children.insert(insert_at, cblock) + + for loop in outer_loops[2].walk(Loop)[13:16]: + cblock = CodeBlock([CompilerDirective("IVDEP")], + CodeBlock.Structure.STATEMENT) + insert_at = loop.parent.children.index(loop) + loop.parent.children.insert(insert_at, cblock) + + for loop in outer_loops[2].walk(Loop)[2:7]: + # Check if any eligible variables appear in subroutine + # call arguments; these lead to false dependency errors + # in the parallel loop transformation that can be + # ignored + ignore_deps_vars = match_call_args(loop, false_dep_vars) + options = {} + if len(ignore_deps_vars) > 0: + options["ignore_dependencies_for"] = ignore_deps_vars + OMP_DO_LOOP_TRANS_STATIC.apply(loop, options) + + for loop in outer_loops[2].walk(Loop)[8:13:2]: + # Check if any eligible variables appear on the LHS of + # assignment expressions to ignore false dependency errors + ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) + options = {} + if len(ignore_deps_vars) > 0: + options["ignore_dependencies_for"] = ignore_deps_vars + + OMP_DO_LOOP_TRANS_STATIC.apply(loop, options) + + except (TransformationError, IndexError) as err: + logging.warning("Parallelisation of the 2nd region failed: %s", err) diff --git a/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_initiation_ctl.py b/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_initiation_ctl.py new file mode 100644 index 000000000..f0d19a243 --- /dev/null +++ b/applications/ngarch/optimisation/esnz-cascade/transmute/large_scale_cloud/pc2_initiation_ctl.py @@ -0,0 +1,37 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +""" +Optimisation script that replaces existing OpenMP parallelisation with +PSyclone-generated directives to parallelise additional loops. +""" + +import logging +from psyclone.transformations import TransformationError +from psyclone.psyir.nodes import Loop +from transmute_psytrans.transmute_functions import ( + get_outer_loops, + OMP_PARALLEL_LOOP_DO_TRANS_STATIC, +) + + +def trans(psyir): + """ + Apply OpenMP Directives + """ + + # Identify outer loops in the subroutine + outer_loops = [loop for loop in get_outer_loops(psyir) + if not loop.ancestor(Loop)] + + try: + # Parallelise k-loops and i-loops (j-loops have a trip count of 1) + for loop in outer_loops: + if loop.variable.name == 'k': + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop) + elif loop.variable.name == 'j': + OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop.walk(Loop)[1]) + except (TransformationError, IndexError) as err: + logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/ngarch/optimisation/meto-ex1a/transmute b/applications/ngarch/optimisation/meto-ex1a/transmute new file mode 120000 index 000000000..40172f606 --- /dev/null +++ b/applications/ngarch/optimisation/meto-ex1a/transmute @@ -0,0 +1 @@ +../../../lfric_atm/optimisation/meto-ex1a/transmute \ No newline at end of file diff --git a/applications/ngarch/optimisation/meto-ex1a/transmute/gravity_wave_drag/gw_ussp_mod.py b/applications/ngarch/optimisation/meto-ex1a/transmute/gravity_wave_drag/gw_ussp_mod.py deleted file mode 100644 index 67261d8b2..000000000 --- a/applications/ngarch/optimisation/meto-ex1a/transmute/gravity_wave_drag/gw_ussp_mod.py +++ /dev/null @@ -1,124 +0,0 @@ -# ----------------------------------------------------------------------------- -# (C) Crown copyright Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -# ----------------------------------------------------------------------------- -""" -PSyclone Script for applying OpenMP transformations to Spectral Gravity Wave. - -Provides: - - `trans(psyir)`: orchestrates all OpenMP transformations. - * Forces a dynamic-scheduled OMP **PARALLEL DO** over - `do i = 1, meta_segments%num_segments` with an explicit PRIVATE list. - * Clusters adjacent top-level loops into **PARALLEL regions** to amortize - thread overheads. - * Applies **STATIC-scheduled** OMP DO / PARALLEL DO to identified heavy - k-loops (profiling hotspots). - -Context (specific to gw_ussp_mod.F90): - - Default scheduling is **static** everywhere **except** for the - `meta_segments%num_segments` loop, which is explicitly **dynamic** to - accommodate variable per-segment workloads. - - Certain scalars are initialised prior to OpenMP transformation so that - backends that emit FIRSTPRIVATE have a well-defined initial value. - -Rationale: - - Profiling indicates k-index loops writing to heavy variables dominate - runtime. Static scheduling generally performs best for these loops, while - the meta-segmentation loop benefits from dynamic scheduling due to load - imbalance. - - Grouping adjacent outer loops into a single parallel region reduces - enter/exit overhead and improves locality. - -Future Work: - - As PSyclone evolves, revisit nowait/lastprivate usage and refine region - boundaries. -""" -import logging -from psyclone.psyir.nodes import Routine -from transmute_psytrans.transmute_functions import ( - add_parallel_do_over_meta_segments, - parallel_regions_for_clustered_loops, - omp_do_for_heavy_loops, - get_compiler, -) - -# ------------------------------------------------------------------------------ -# OpenMP transformation objects -# -# Policy: -# - STATIC schedule by default for heavy k-loops (best throughput observed). -# - DYNAMIC schedule **only** for the PARALLEL DO -# over meta_segments%num_segments. -# ------------------------------------------------------------------------------ -# NOTE: OMP_* transform instances now live in the generic module; kept comment -# here to preserve file style and intent. - -# Variables considered "heavy" when written inside loops: -# - HEAVY_VARS_K → for k-loops -# - HEAVY_VARS_I → for i-loops -# These guide where OMP DO / PARALLEL DO (static) should be applied. -HEAVY_VARS_K = { - "rhont_smallhalo", "rho_th", "udotk", "g_x", "g_y", "t_inc", - "r_u", "r_v", "g_xp_smallhalo", "g_yp_smallhalo", -} -HEAVY_VARS_I = {"rho_th", "nbv", "udotk"} - -# --- meta_segments PARALLEL DO (forced, dynamic), with explicit privates ---- -# Explicit PRIVATE list for the meta-segmentation PARALLEL DO -_META_PRIVATES = [ - # scalars - "ii", "jj", "ss", "i", "k", "jdir", - # allocatables used per-segment - "s_sin_theta_lat", "s_totalppn", "s_rho_th", "s_nbv", "s_udotk", "s_fptot", -] - - -# ------------------------------------------------------------------------------ -# Entry point -# ------------------------------------------------------------------------------ -def trans(psyir): - """ - Entry point for OpenMP transformations for `gw_ussp_mod.F90`. - - Passes: - 1) Force PARALLEL DO (dynamic) for meta-segmentation loop. - 2) Cluster adjacent top-level loops into PARALLEL regions. - 3) Apply OMP DO / PARALLEL DO (static) to heavy k-loops. - """ - logging.info( - "gw_ussp_mod.F90 Psyclone Optimisation for the CPU is running." - ) - - compiler = get_compiler() - - # GCC currently has issues with firstprivated indexes, - # which is soon to be resolved in PSyclone. - # However for now we will avoid using OpenMP - # around meta_segments with with GCC. - if compiler == "gnu": - logging.info( - "Skipping gw_ussp_mod meta_segment optimisations for GCC." - ) - else: - # 1) Force a PARALLEL DO around meta_segments%num_segments (dynamic) - for routine in psyir.walk(Routine): - add_parallel_do_over_meta_segments( - routine, - container_name="meta_segments", - member_name="num_segments", - privates=_META_PRIVATES, - ) - - # 2) Cluster adjacent outer loops into PARALLEL regions (no schedule here) - for routine in psyir.walk(Routine): - parallel_regions_for_clustered_loops(routine) - - # 3) Add OMP DO / PARALLEL DO on heavy k- and i-loops (static) - # (Skip the special i-loop handled above.) - for routine in psyir.walk(Routine): - omp_do_for_heavy_loops(routine, "k", HEAVY_VARS_K) - omp_do_for_heavy_loops( - routine, "i", HEAVY_VARS_I, - skip_member_count=("i", "meta_segments", "num_segments") - ) diff --git a/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py b/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py deleted file mode 100644 index cc3235be5..000000000 --- a/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/bm_tau_kernel_mod.py +++ /dev/null @@ -1,49 +0,0 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -############################################################################## -""" -Optimisation script that adds OpenMP worksharing-loop directives to speed up -loops before and after a PC2 subroutine call. Some PSyclone dependency errors -need to be overridden; these assignments can be safely parallelised. -""" - -import logging -from psyclone.transformations import TransformationError -from psyclone.psyir.nodes import Loop -from transmute_psytrans.transmute_functions import ( - match_lhs_assignments, - OMP_PARALLEL_LOOP_DO_TRANS_STATIC -) - -# Variables that appear on the left-hand side of assignments -# for which PSyclone dependency errors can be ignored -false_dep_vars = [ - "tau_dec_bm", - "tau_hom_bm", - "tau_mph_bm" -] - - -def trans(psyir): - """ - Apply OpenMP Directives - """ - - # Add parallel do directives to outer loops - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - # Check if any eligible variables appear on the LHS of - # assignment expressions; these lead to false dependency - # errors in the parallel loop transformation that can be - # ignored - ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) - options = {} - if len(ignore_deps_vars) > 0: - options["ignore_dependencies_for"] = ignore_deps_vars - - try: - OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py b/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py deleted file mode 100644 index d7748acfa..000000000 --- a/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/pc2_conv_coupling_kernel_mod.py +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -############################################################################## -""" -Optimisation script that adds OpenMP parallel do worksharing-loop directives. -The main loop requires dynamic schedule to improve load balancing between -threads. Some PSyclone dependency errors and a subroutine thread safety -check need to be overridden; these assignments and subroutine call can be -safely parallelised. Multiple arrays need to be declared OpenMP-private. -""" - -import logging -from psyclone.transformations import (OMPLoopTrans, TransformationError) -from psyclone.psyir.nodes import Loop -from transmute_psytrans.transmute_functions import ( - set_pure_subroutines, - match_lhs_assignments, - OMP_PARALLEL_LOOP_DO_TRANS_STATIC -) - -# Variables that appear on the left-hand side of assignments -# for which PSyclone dependency errors can be ignored -false_dep_vars = [ - "dt_conv_wth", - "dmv_conv_wth", - "dmcl_conv_wth", - "dcfl_conv_wth", - "dbcf_conv_wth" -] - -# Arrays that appear on the left-hand side of assignments -# which trigger automatic array privatisation in PSyclone -private_arrays = [ - "p_forcing", - "p_work", - "t_forcing", - "t_work", - "qv_forcing", - "cfl_forcing", - "qv_work", - "qcl_work", - "cfl_work", - "cff_work", - "bcf_work", - "t_incr", - "qv_incr", - "qcl_incr", - "cfl_incr", - "bcf_incr", -] - - -def trans(psyir): - """ - Apply OpenMP Directives - """ - - # Declare subroutine "pc2_hom_conv" as pure to enable parallelisation - # of the encompassing loop - set_pure_subroutines(psyir, "pc2_hom_conv") - - # OMPLoopTrans supports automatic array privatisation - omp_pardo_dyn = OMPLoopTrans(omp_schedule="dynamic", - omp_directive="paralleldo") - - # Add parallel do directives to outer loops - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - # Check if any variables appear on the LHS of assignment - # expressions that require "privatisation" or lead to false - # dependency errors in the parallel loop transformation. - options = {"privatise_arrays": - len(match_lhs_assignments(loop, private_arrays)) > 0} - ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) - if len(ignore_deps_vars) > 0: - options["ignore_dependencies_for"] = ignore_deps_vars - - # The loop with privatised arrays also needs dynamic schedule - if options["privatise_arrays"]: - try: - omp_pardo_dyn.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPLoopTrans failed: %s", err) - else: - try: - OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPLoopTrans failed: %s", err) diff --git a/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py b/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py deleted file mode 100644 index ed4a0e90e..000000000 --- a/applications/ngarch/optimisation/meto-ex1a/transmute/kernel/pc2_initiation_kernel_mod.py +++ /dev/null @@ -1,57 +0,0 @@ -############################################################################## -# (c) Crown copyright 2025 Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -############################################################################## -""" -Optimisation script that adds OpenMP worksharing-loop directives to speed up -various loops. Some PSyclone dependency errors need to be overridden; these -assignments can be safely parallelised. -""" - -import logging -from psyclone.transformations import TransformationError -from psyclone.psyir.nodes import Loop -from transmute_psytrans.transmute_functions import ( - match_lhs_assignments, - OMP_PARALLEL_LOOP_DO_TRANS_STATIC -) - -# Variables that appear on the left-hand side of assignments -# for which PSyclone dependency errors can be ignored -false_dep_vars = [ - "dtheta_inc_wth", - "dmv_inc_wth", - "dmcl_inc_wth", - "dmci_inc_wth", - "dms_inc_wth", - "dcfl_inc_wth", - "dcff_inc_wth", - "dbcf_inc_wth", - "sskew_bm", - "svar_bm", - "svar_tb" -] - - -def trans(psyir): - """ - Apply OpenMP Directives - """ - - # Add parallel do directives to outer loops - for loop in psyir.walk(Loop): - if not loop.ancestor(Loop): - # Check if any eligible variables appear on the LHS of - # assignment expressions; these lead to false dependency - # errors in the parallel loop transformation that can be - # ignored - ignore_deps_vars = match_lhs_assignments(loop, false_dep_vars) - options = {} - if len(ignore_deps_vars) > 0: - options["ignore_dependencies_for"] = ignore_deps_vars - - try: - OMP_PARALLEL_LOOP_DO_TRANS_STATIC.apply(loop, options) - except (TransformationError, IndexError) as err: - logging.warning("OMPParallelLoopTrans failed: %s", err) diff --git a/applications/ngarch/rose-meta/lfric-ngarch/version30_31.py b/applications/ngarch/rose-meta/lfric-ngarch/version30_31.py new file mode 100644 index 000000000..642cfe160 --- /dev/null +++ b/applications/ngarch/rose-meta/lfric-ngarch/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-ngarch + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/ngarch/rose-meta/lfric-ngarch/versions.py b/applications/ngarch/rose-meta/lfric-ngarch/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/ngarch/rose-meta/lfric-ngarch/versions.py +++ b/applications/ngarch/rose-meta/lfric-ngarch/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/ngarch/rose-meta/lfric-ngarch/vn3.1/rose-meta.conf b/applications/ngarch/rose-meta/lfric-ngarch/vn3.1/rose-meta.conf new file mode 100644 index 000000000..0d4e795f6 --- /dev/null +++ b/applications/ngarch/rose-meta/lfric-ngarch/vn3.1/rose-meta.conf @@ -0,0 +1,19 @@ +import=lfric-gungho/vn3.1 + +[namelist:ngarch] +compulsory=true +description= +ns=namelist/ngarch +title=ngarch + +[namelist:ngarch=method] +compulsory=true +description=Which ngarch timestep method to use +!enumeration=true +help=The method will be used instead of the one set by the 'method' option in the + =timestepping namelist, though that option must still be set to a valid value. + =Setting this value to 'lfricatm' will not override the method option and the + =app will continue using the setting set in timestepping. +sort-key= +value-titles=LFRic-ATM, CASIM, Boundary Layer +values='lfric_atm', 'casim', 'bl' diff --git a/applications/ngarch/source/algorithm/boundary_layer_timestep_mod.x90 b/applications/ngarch/source/algorithm/boundary_layer_timestep_mod.x90 index 27cac265b..e2ba03076 100644 --- a/applications/ngarch/source/algorithm/boundary_layer_timestep_mod.x90 +++ b/applications/ngarch/source/algorithm/boundary_layer_timestep_mod.x90 @@ -57,7 +57,7 @@ contains water_extraction, lake_evap, & theta_star_surf, qv_star_surf, & recip_l_mo_sea, rhostar, & - h_blend_orog, t1_sd_2d, q1_sd_2d + t1_sd_2d, q1_sd_2d type( field_array_type ), pointer :: mr type(field_collection_type), pointer :: prognostic_fields, & @@ -121,7 +121,7 @@ contains turbulence_fields, convection_fields, cloud_fields, & surface_fields, soil_fields, snow_fields, & aerosol_fields, recip_l_mo_sea, rhostar, & - h_blend_orog, t1_sd_2d, q1_sd_2d ) + t1_sd_2d, q1_sd_2d ) ! Call the algorithm call log_event( "Running BOUNDARY LAYER EXP", LOG_LEVEL_INFO ) @@ -136,7 +136,7 @@ contains cloud_fields, & surface_fields, & recip_l_mo_sea, rhostar, & - h_blend_orog, t1_sd_2d, q1_sd_2d, & + t1_sd_2d, q1_sd_2d, & modeldb%clock ) call log_event( "Running BOUNDARY LAYER IMP", LOG_LEVEL_INFO ) diff --git a/applications/ngarch/source/ngarch.f90 b/applications/ngarch/source/ngarch.f90 index 691f84968..29a1c7614 100644 --- a/applications/ngarch/source/ngarch.f90 +++ b/applications/ngarch/source/ngarch.f90 @@ -8,7 +8,7 @@ !> @details Runs a GungHo model with a custom step method program ngarch - use cli_mod, only : get_initial_filename + use cli_mod, only : parse_command_line use driver_collections_mod, only : init_collections, final_collections use constants_mod, only : precision_real use driver_comm_mod, only : init_comm, final_comm @@ -20,6 +20,9 @@ program ngarch use log_mod, only : log_event, & log_level_trace, & log_scratch_space + use namelist_mod, only : namelist_type + use timing_mod, only : init_timing, final_timing + use io_config_mod, only : timer_output_path use ngarch_mod, only : ngarch_required_namelists use gungho_driver_mod, only : initialise, finalise, step @@ -28,9 +31,13 @@ program ngarch implicit none ! The technical and scientific state - type( modeldb_type ) :: modeldb - character(*), parameter :: application_name = "ngarch" - character(:), allocatable :: filename + type( modeldb_type ) :: modeldb + character(*), parameter :: application_name = "ngarch" + character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) call modeldb%configuration%initialise( application_name, table_len=10 ) call modeldb%values%initialise( 'values', 5 ) @@ -56,13 +63,16 @@ program ngarch modeldb%mpi => global_mpi call init_comm( application_name, modeldb ) - call get_initial_filename( filename ) call init_config( filename, & ngarch_required_namelists, & modeldb%configuration ) deallocate( filename ) call init_logger( modeldb%mpi%get_comm(), application_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, application_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) @@ -79,6 +89,7 @@ program ngarch call finalise( application_name, modeldb ) call final_time( modeldb ) call final_collections() + call final_timing( application_name ) call final_logger( application_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/shallow_water/example/configuration.nml b/applications/shallow_water/example/configuration.nml index d4ab292f9..94bc7b36e 100644 --- a/applications/shallow_water/example/configuration.nml +++ b/applications/shallow_water/example/configuration.nml @@ -178,6 +178,7 @@ tau_u = 0.0 &transport adjust_theta=.false. adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection = .true. calculate_detj = 'upwind' diff --git a/applications/shallow_water/example/iodef.xml b/applications/shallow_water/example/iodef.xml index 6b6e9cfb5..14f51a55f 100644 --- a/applications/shallow_water/example/iodef.xml +++ b/applications/shallow_water/example/iodef.xml @@ -136,7 +136,7 @@ performance - 1.0 + 1.0 diff --git a/applications/shallow_water/rose-meta/lfric-shallow_water/version30_31.py b/applications/shallow_water/rose-meta/lfric-shallow_water/version30_31.py new file mode 100644 index 000000000..0758727f6 --- /dev/null +++ b/applications/shallow_water/rose-meta/lfric-shallow_water/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-shallow_water + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/shallow_water/rose-meta/lfric-shallow_water/versions.py b/applications/shallow_water/rose-meta/lfric-shallow_water/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/shallow_water/rose-meta/lfric-shallow_water/versions.py +++ b/applications/shallow_water/rose-meta/lfric-shallow_water/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/shallow_water/rose-meta/lfric-shallow_water/vn3.1/rose-meta.conf b/applications/shallow_water/rose-meta/lfric-shallow_water/vn3.1/rose-meta.conf new file mode 100644 index 000000000..806760109 --- /dev/null +++ b/applications/shallow_water/rose-meta/lfric-shallow_water/vn3.1/rose-meta.conf @@ -0,0 +1,136 @@ +import=lfric-gungho/vn3.1 + +[namelist:shallow_water_settings] +compulsory=true +description=Shallow Water miniapp specific settings. +ns=namelist/swe_constants +title=Shallow water equation settings + +[namelist:shallow_water_settings=momentum_form] +compulsory=true +description=Either the momentum or vector invariant form of the shallow water equations. +!enumeration=true +help=Choose either the momentum (advective) form, or the vector inviariant form + =of the shallow water momentum equations. The default setting is vector-invariant. +sort-key= +value-titles=Momentum, Vector-Invariant +values='momentum', 'vector_invariant' + +[!namelist:shallow_water_settings=ref_gp] +compulsory=true +description=Reference geopotential for the shallow water miniapp. +fail-if=this <= 0.0 ; +help=Given by g*H for reference height H and gravity g. +!kind=default +sort-key= +type=real + +[namelist:shallow_water_settings=swe_test] +compulsory=true +description=Initial conditions for the Shallow Water miniapp. +!enumeration=true +fail-if=this == "'swe_geostr_imbalance'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'swe_mountain'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'swe_galewsky'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'swe_thermal_dbl_vortex'" and namelist:base_mesh=geometry == "'spherical'" ; +help=Shallow Water Test Cases + =swe_geostr_balance : Shallow water geostrophic balance test (planar sin wave|spherical Williamson2) + =swe_geostrophic_imbalance : A shallow water wave in geostrophic imbalance (planar) + =swe_gaussian_hill : A single advected gaussian hill for the shallow water equations (planar|spherical) + =swe_mountain : Steady flow perturbed by a mountain (spherical Williamson5) + =swe_galewsky : Barotropic perturbation of steady jet stream (spherical) + =swe_thermal_dbl_vortex : A double vortex for the thermal shallow water equations (planar) + =swe_vortex_field : A vortex field for the shallow water equations (planar/spherical) +sort-key= +value-titles=Shallow Water Geostrophic balance, Shallow Water Geostrophic imbalance, + =Shallow water Gaussian hill, Shallow water mountain, Shallow Water Galewsky, + =Thermal Shallow Water Double vortex, Shallow Water Vortex field +values='swe_geostr_balance', 'swe_geostr_imbalance', 'swe_gaussian_hill', + ='swe_mountain', 'swe_galewsky', 'swe_thermal_dbl_vortex', 'swe_vortex_field' + +[namelist:shallow_water_settings=thermal_swe] +compulsory=true +description=Turns on the thermal shallow water equations. +help=The thermal shallow water equations include the buoyancy. + =This is a switch on whether to use thermal shallow water equations, + =or the usual shallow water equations in the miniapp. +!kind=default +sort-key= +type=logical + +[namelist:shallow_water_settings=time_scheme] +compulsory=true +description=The time stepping method used (semi-implicit or explicit). +!enumeration=true +help=Choose either a semi-implicit or an explicit time stepping scheme + =for the shallow water equations. The semi-implicit scheme is an + =iterative method and has good stability properties. The explicit + =scheme uses Runge-Kutta SSP3 for the time stepping. +sort-key= +value-titles=Semi-Implicit, Explicit SSPRK3, Explicit RK4 +values='semi_implicit', 'ssprk3', 'rk4' + +[namelist:shallow_water_test_coeff] +compulsory=true +description=Shallow Water miniapp Gaussian hill test settings. +ns=namelist/swe_test_coeff +title=Shallow water test cases coefficients + +[!namelist:shallow_water_test_coeff=mag1] +compulsory=true +description=Gaussian hill magnitude. +fail-if=this <= 0.0 ; +help=For Gaussian hill test cases, this sets the inital profile magnitude, + =with the initial profile given by ref_gp + mag * exp(...). +!kind=default +sort-key= +type=real + +[!namelist:shallow_water_test_coeff=u1] +compulsory=true +description=x/zonal velocity magnitude. +help=Initial magnitude of u for the Gaussian hill test case. +!kind=default +sort-key= +type=real + +[!namelist:shallow_water_test_coeff=u2] +compulsory=true +description=y/meridional velocity magnitude. +help=Initial magnitude of v for the Gaussian hill test case. +!kind=default +sort-key= +type=real + +[!namelist:shallow_water_test_coeff=x1] +compulsory=true +description=Gaussian hill centre in x/longitude. +help=Geopotential Gaussian hill centre in x for the Gaussian hill test case. +!kind=default +sort-key= +type=real + +[!namelist:shallow_water_test_coeff=xr] +compulsory=true +description=Gaussian hill extent in x/longitude. +fail-if=this <= 0.0 ; +help=Geopotential Gaussian hill extent in x for the Gaussian hill test case. +!kind=default +sort-key= +type=real + +[!namelist:shallow_water_test_coeff=y1] +compulsory=true +description=Gaussian hill centre in y/latitude. +help=Geopotential Gaussian hill centre in y for Gaussian hill test case. +!kind=default +sort-key= +type=real + +[!namelist:shallow_water_test_coeff=yr] +compulsory=true +description=Gaussian hill extent in y/latitude. +help=Geopotential Gaussian hill extent in y for Gaussian hill test case. +!kind=default +sort-key= +type=real diff --git a/applications/shallow_water/source/algorithm/swe_mixed_diag_precon_alg_mod.x90 b/applications/shallow_water/source/algorithm/swe_mixed_diag_precon_alg_mod.x90 index d59789449..d511cbfb4 100644 --- a/applications/shallow_water/source/algorithm/swe_mixed_diag_precon_alg_mod.x90 +++ b/applications/shallow_water/source/algorithm/swe_mixed_diag_precon_alg_mod.x90 @@ -18,7 +18,6 @@ module swe_mixed_diag_precon_alg_mod use field_mod, only: field_type use field_indices_mod, only: isw_u, isw_g, isw_b use fs_continuity_mod, only: W1, W2, W3 - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -28,7 +27,8 @@ module swe_mixed_diag_precon_alg_mod use sci_field_vector_mod, only: field_vector_type use sci_preconditioner_mod, only: abstract_preconditioner_type use shallow_water_settings_config_mod, only: thermal_swe - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use vector_mod, only: abstract_vector_type implicit none @@ -119,8 +119,9 @@ contains y_vec_u => null(), & y_vec_g => null(), & y_vec_b => null() + integer(tik) :: id - if ( subroutine_timers ) call timer('swe_mixed_diag_preconditioner_alg') + if ( LPROF ) call start_timing( id, 'swe_mixed_diag_preconditioner_alg' ) select type(x) type is(field_vector_type) @@ -161,7 +162,7 @@ contains nullify( x_vec_u, x_vec_g, x_vec_b ) nullify( y_vec_u, y_vec_g, y_vec_b ) - if ( subroutine_timers ) call timer('swe_mixed_diag_preconditioner_alg') + if ( LPROF ) call stop_timing( id, 'swe_mixed_diag_preconditioner_alg' ) end subroutine apply_swe_mixed_diag_preconditioner diff --git a/applications/shallow_water/source/algorithm/swe_mixed_schur_precon_alg_mod.x90 b/applications/shallow_water/source/algorithm/swe_mixed_schur_precon_alg_mod.x90 index e426f6275..7b497585e 100644 --- a/applications/shallow_water/source/algorithm/swe_mixed_schur_precon_alg_mod.x90 +++ b/applications/shallow_water/source/algorithm/swe_mixed_schur_precon_alg_mod.x90 @@ -76,7 +76,6 @@ module swe_mixed_schur_precon_alg_mod use field_mod, only: field_type use field_indices_mod, only: isw_u, isw_g, isw_b use fs_continuity_mod, only: W1, W2, W3 - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO, & @@ -89,7 +88,8 @@ module swe_mixed_schur_precon_alg_mod use shallow_water_settings_config_mod, only: ref_gp, & thermal_swe use timestepping_config_mod, only: dt - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use vector_mod, only: abstract_vector_type use sci_field_minmax_alg_mod, only: log_field_minmax @@ -268,8 +268,9 @@ contains type(field_type), pointer :: y_vec_u => null(), & y_vec_g => null(), & y_vec_b => null() + integer(tik) :: id - if ( subroutine_timers ) call timer('swe_mixed_schur_preconditioner_alg') + if ( LPROF ) call start_timing( id, 'swe_mixed_schur_preconditioner_alg' ) select type(x) type is(field_vector_type) @@ -316,7 +317,7 @@ contains nullify( y_vec_u, y_vec_g, y_vec_b ) - if ( subroutine_timers ) call timer('swe_mixed_schur_preconditioner_alg') + if ( LPROF ) call stop_timing( id, 'swe_mixed_schur_preconditioner_alg' ) end subroutine apply_swe_mixed_schur_preconditioner diff --git a/applications/shallow_water/source/algorithm/swe_timestep_alg_mod.x90 b/applications/shallow_water/source/algorithm/swe_timestep_alg_mod.x90 index c66673e57..d509b19b4 100644 --- a/applications/shallow_water/source/algorithm/swe_timestep_alg_mod.x90 +++ b/applications/shallow_water/source/algorithm/swe_timestep_alg_mod.x90 @@ -27,13 +27,13 @@ module swe_timestep_alg_mod use model_clock_mod, only: model_clock_type ! Configuration options - use io_config_mod, only: subroutine_timers use shallow_water_settings_config_mod, & only: ref_gp, & thermal_swe, & time_scheme, & time_scheme_semi_implicit - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use timestepping_config_mod, only: alpha, & outer_iterations, & inner_iterations @@ -433,8 +433,9 @@ contains real(kind=r_def) :: alpha_dt real(kind=r_def) :: beta_dt type(field_type) :: wind_prev + integer(tik) :: id_sw_alg - if ( subroutine_timers ) call timer('shallow_water_alg_si') + if ( LPROF ) call start_timing( id_sw_alg, 'shallow_water_alg_si' ) !--- Do a single timestep -------------------------------------------------- ! set up state variable @@ -584,7 +585,7 @@ contains end if call state%export_field(q, isw_q) - if ( subroutine_timers ) call timer('shallow_water_alg_si') + if ( LPROF ) call stop_timing( id_sw_alg, 'shallow_water_alg_si' ) end subroutine swe_timestep_alg_si @@ -742,8 +743,9 @@ contains ! Variables after forward Euler step type( field_type ) :: wind_fe1, geopot_fe1, buoyancy_fe1, q_fe1 type( field_type ) :: wind_fe2, geopot_fe2, buoyancy_fe2, q_fe2 + integer(tik) :: id_swe_ssprk3 - if ( subroutine_timers ) call timer('swe_timestep_alg_ssprk3') + if ( LPROF ) call start_timing( id_swe_ssprk3, 'swe_timestep_alg_ssprk3' ) !--- Do a single timestep -------------------------------------------------- ! Initialise variables @@ -830,7 +832,7 @@ contains aX_plus_bY( buoyancy, onethird, buoyancy_n, twothird, buoyancy_fe2 ) ) call swe_init_vorticity_alg(wind, geopot, q) - if ( subroutine_timers ) call timer('swe_timestep_alg_ssprk3') + if ( LPROF ) call stop_timing( id_swe_ssprk3, 'swe_timestep_alg_ssprk3' ) end subroutine swe_timestep_alg_ssprk3 @@ -892,8 +894,9 @@ contains real(kind=r_def), parameter :: one_sixth = 1.0_r_def/6.0_r_def real(kind=r_def), parameter :: one_twenty_fourth = 1.0_r_def/24.0_r_def real(kind=r_def), parameter :: three_eighths = 3.0_r_def/8.0_r_def + integer(kind=tik) :: id_swe_rk4 - if ( subroutine_timers ) call timer('swe_timestep_alg_rk4') + if ( LPROF ) call start_timing( id_swe_rk4, 'swe_timestep_alg_rk4' ) !--- Do a single timestep -------------------------------------------------- ! Initialise all the variables @@ -1036,7 +1039,7 @@ contains inc_X_plus_bY( buoyancy, one_sixth, buoyancy_fe3 ) ) call swe_init_vorticity_alg(wind, geopot, q) - if ( subroutine_timers ) call timer('swe_timestep_alg_rk4') + if ( LPROF ) call stop_timing( id_swe_rk4, 'swe_timestep_alg_rk4' ) end subroutine swe_timestep_alg_rk4 diff --git a/applications/shallow_water/source/algorithm/swe_transport_control_alg_mod.x90 b/applications/shallow_water/source/algorithm/swe_transport_control_alg_mod.x90 index 996729ec7..ce4364156 100644 --- a/applications/shallow_water/source/algorithm/swe_transport_control_alg_mod.x90 +++ b/applications/shallow_water/source/algorithm/swe_transport_control_alg_mod.x90 @@ -40,6 +40,8 @@ module swe_transport_control_alg_mod momentum_form, & momentum_form_momentum, & momentum_form_vector_invariant + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_config_mod, only: cheap_update use transport_controller_mod, only: transport_controller_type use transport_metadata_mod, only: transport_metadata_type @@ -147,8 +149,6 @@ contains use operator_mod, only: operator_type use transport_field_mod, only: transport_field use wind_transport_alg_mod, only: wind_transport_alg - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer implicit none @@ -200,8 +200,9 @@ contains ! Quadrature type(quadrature_xyoz_type) :: qr type(quadrature_rule_gaussian_type) :: quadrature_rule + integer(tik) :: id_cont - if ( subroutine_timers ) call timer('swe_transport_control_alg_step') + if ( LPROF ) call start_timing( id_cont, 'swe_transport_control_alg_step' ) ! ------------------------------------------------------------------------ ! ! Pre-transport initialisation tasks @@ -365,7 +366,7 @@ contains call transport_controller%finalise() - if ( subroutine_timers ) call timer('swe_transport_control_alg_step') + if ( LPROF ) call stop_timing( id_cont, 'swe_transport_control_alg_step' ) end subroutine swe_transport_control_alg_step @@ -391,8 +392,6 @@ contains model_clock ) use transport_field_mod, only: transport_field - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer use transport_enumerated_types_mod, only: equation_form_conservative, & equation_form_advective, & equation_form_consistent @@ -420,8 +419,9 @@ contains ! Parameters for transport runtime integer(i_def), parameter :: outer = 1 logical(l_def), parameter :: cheap_update_flag = .false. + integer(tik) :: id_swe_tracer - if ( subroutine_timers ) call timer('swe_transport_control_alg_step') + if ( LPROF ) call start_timing( id_swe_tracer, 'swe_tracer_transport_alg' ) ! Initialise the main transport controller --------------------------------- call transport_controller%initialise(model_clock, mass_n, wind_n, wind_np1) @@ -513,7 +513,7 @@ contains call transport_controller%finalise() - if ( subroutine_timers ) call timer('swe_tracer_transport_alg') + if ( LPROF ) call stop_timing( id_swe_tracer, 'swe_tracer_transport_alg' ) end subroutine swe_tracer_transport_alg diff --git a/applications/shallow_water/source/driver/shallow_water_model_mod.F90 b/applications/shallow_water/source/driver/shallow_water_model_mod.F90 index f2706ce97..48de3152c 100644 --- a/applications/shallow_water/source/driver/shallow_water_model_mod.F90 +++ b/applications/shallow_water/source/driver/shallow_water_model_mod.F90 @@ -83,6 +83,7 @@ subroutine initialise_infrastructure( program_name, modeldb) character(str_def), allocatable :: base_mesh_names(:) character(str_def), allocatable :: twod_names(:) + integer(i_def), allocatable :: stencil_depths(:) class(extrusion_type), allocatable :: extrusion type(uniform_extrusion_type), allocatable :: extrusion_2d @@ -93,7 +94,6 @@ subroutine initialise_infrastructure( program_name, modeldb) character(str_def) :: prime_mesh_name - integer(i_def) :: stencil_depth integer(i_def) :: geometry integer(i_def) :: method integer(i_def) :: number_of_layers @@ -180,12 +180,15 @@ subroutine initialise_infrastructure( program_name, modeldb) ! Initialise prime/2d meshes ! --------------------------------------------------------- check_partitions = .false. - stencil_depth = get_required_stencil_depth() + allocate(stencil_depths(size(base_mesh_names))) + call get_required_stencil_depth( & + stencil_depths, base_mesh_names, modeldb%configuration & + ) call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & base_mesh_names, extrusion, & - stencil_depth, check_partitions ) + stencil_depths, check_partitions ) allocate( twod_names, source=base_mesh_names ) @@ -222,6 +225,8 @@ subroutine initialise_infrastructure( program_name, modeldb) call create_runtime_constants() deallocate(base_mesh_names) + deallocate(twod_names) + deallocate(stencil_depths) nullify(chi_inventory, panel_id_inventory) end subroutine initialise_infrastructure diff --git a/applications/shallow_water/source/kernel/initial_swe_streamfunc_kernel_mod.F90 b/applications/shallow_water/source/kernel/initial_swe_streamfunc_kernel_mod.F90 index 26df19f6e..b9221ca88 100644 --- a/applications/shallow_water/source/kernel/initial_swe_streamfunc_kernel_mod.F90 +++ b/applications/shallow_water/source/kernel/initial_swe_streamfunc_kernel_mod.F90 @@ -18,8 +18,13 @@ module initial_swe_streamfunc_kernel_mod use constants_mod, only : r_def, i_def, PI use fs_continuity_mod, only : W1 use kernel_mod, only : kernel_type + + use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius use shallow_water_settings_config_mod, & - only : swe_test + only: swe_test implicit none @@ -86,8 +91,6 @@ subroutine initial_swe_streamfunc_code(nlayers, rhs, chi_1, chi_2, chi_3, panel_ use analytic_swe_streamfunction_profiles_mod, & only: analytic_swe_streamfunction - use base_mesh_config_mod, only: geometry, & - geometry_spherical use sci_coordinate_jacobian_mod, only: coordinate_jacobian, & coordinate_jacobian_inverse use coord_transform_mod, only: sphere2cart_vector @@ -135,7 +138,11 @@ subroutine initial_swe_streamfunc_code(nlayers, rhs, chi_1, chi_2, chi_3, panel_ chi_3_cell(df) = chi_3( map_chi(df) ) end do - call coordinate_jacobian( ndf_chi, & + call coordinate_jacobian( coord_system, & + geometry, & + topology, & + scaled_radius, & + ndf_chi, & nqp_h, & nqp_v, & chi_1_cell, & diff --git a/applications/shallow_water/source/kernel/initial_swe_u_kernel_mod.F90 b/applications/shallow_water/source/kernel/initial_swe_u_kernel_mod.F90 index fbad6cef9..6d93ab3d9 100644 --- a/applications/shallow_water/source/kernel/initial_swe_u_kernel_mod.F90 +++ b/applications/shallow_water/source/kernel/initial_swe_u_kernel_mod.F90 @@ -19,13 +19,17 @@ module initial_swe_u_kernel_mod ANY_DISCONTINUOUS_SPACE_3 use constants_mod, only : r_def, PI, i_def use fs_continuity_mod, only : W2 - use initial_wind_config_mod, only : profile_sin_uv, & - profile, sbr_angle_lat, sbr_angle_lon, & - u0, v0, shear, wavelength - use kernel_mod, only : kernel_type + + use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical + use finite_element_config_mod, only: coord_system + use initial_wind_config_mod, only: profile_sin_uv, & + profile, sbr_angle_lat, sbr_angle_lon, & + u0, v0, shear, wavelength + use planet_config_mod, only: scaled_radius use shallow_water_settings_config_mod, & - only : swe_test + only: swe_test implicit none @@ -94,8 +98,6 @@ subroutine initial_swe_u_code( nlayers, rhs, & nqp_h, nqp_v, wqp_h, wqp_v ) use analytic_swe_wind_profiles_mod, only : analytic_swe_wind - use base_mesh_config_mod, only : geometry, & - geometry_spherical use sci_coordinate_jacobian_mod, only : coordinate_jacobian use coord_transform_mod, only : sphere2cart_vector use sci_chi_transform_mod, only : chi2llr, chi2xyz @@ -142,7 +144,11 @@ subroutine initial_swe_u_code( nlayers, rhs, & chi_3_cell(df) = chi_3( map_chi(df) ) end do - call coordinate_jacobian(ndf_chi, & + call coordinate_jacobian( coord_system, & + geometry, & + topology, & + scaled_radius, & + ndf_chi, & nqp_h, & nqp_v, & chi_1_cell, & diff --git a/applications/shallow_water/source/kernel/initial_vorticity_v2_kernel_mod.F90 b/applications/shallow_water/source/kernel/initial_vorticity_v2_kernel_mod.F90 index 4cb12608c..f5a5b5c26 100644 --- a/applications/shallow_water/source/kernel/initial_vorticity_v2_kernel_mod.F90 +++ b/applications/shallow_water/source/kernel/initial_vorticity_v2_kernel_mod.F90 @@ -25,12 +25,13 @@ module initial_vorticity_v2_kernel_mod use kernel_mod, only: kernel_type use sci_coordinate_jacobian_mod, only: coordinate_jacobian, & coordinate_jacobian_inverse - use base_mesh_config_mod, only: geometry, & - geometry_spherical, & - f_lat use rotation_vector_mod, only: rotation_vector_fplane, & rotation_vector_sphere - use planet_config_mod, only: scaled_omega + + use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical, f_lat + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius, scaled_omega implicit none @@ -165,7 +166,11 @@ subroutine initial_vorticity_v2_code(nlayers, r_q, curl_u, geopot, & rotation_vector) end if - call coordinate_jacobian(ndf_chi, & + call coordinate_jacobian(coord_system, & + geometry, & + topology, & + scaled_radius, & + ndf_chi, & nqp_h, & nqp_v, & chi_1_e, & diff --git a/applications/shallow_water/source/shallow_water.f90 b/applications/shallow_water/source/shallow_water.f90 index 7118a3408..05f686f7a 100644 --- a/applications/shallow_water/source/shallow_water.f90 +++ b/applications/shallow_water/source/shallow_water.f90 @@ -14,7 +14,7 @@ program shallow_water - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use driver_collections_mod, only: init_collections, final_collections use driver_comm_mod, only: init_comm, final_comm use driver_config_mod, only: init_config, final_config @@ -22,7 +22,6 @@ program shallow_water use driver_log_mod, only: init_logger, final_logger use driver_modeldb_mod, only: modeldb_type use driver_time_mod, only: init_time, final_time - use driver_timer_mod, only: init_timers, final_timers use lfric_mpi_mod, only: global_mpi use log_mod, only: log_event, & log_level_trace, & @@ -31,6 +30,9 @@ program shallow_water use shallow_water_driver_mod, only: initialise, & step, & finalise + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path implicit none @@ -40,6 +42,11 @@ program shallow_water type(modeldb_type) :: modeldb character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) + modeldb%mpi => global_mpi call modeldb%configuration%initialise( program_name, table_len=10 ) @@ -56,11 +63,13 @@ program shallow_water call modeldb%io_contexts%initialise(program_name, 100) call init_comm( program_name, modeldb ) - call get_initial_filename( filename ) call init_config( filename, shallow_water_required_namelists, & modeldb%configuration ) call init_logger( global_mpi%get_comm(), program_name ) - call init_timers( program_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, program_name, timer_output_path ) + nullify( io_nml ) call init_counters( program_name ) call init_collections() call init_time( modeldb ) @@ -80,7 +89,7 @@ program shallow_water call final_time( modeldb ) call final_collections() call final_counters( program_name ) - call final_timers( program_name ) + call final_timing( program_name ) call final_logger( program_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/shallow_water/unit-test/kernel/initial_geopot_kernel_mod_test.pf b/applications/shallow_water/unit-test/kernel/initial_geopot_kernel_mod_test.pf index fe44262b4..75d5fe402 100644 --- a/applications/shallow_water/unit-test/kernel/initial_geopot_kernel_mod_test.pf +++ b/applications/shallow_water/unit-test/kernel/initial_geopot_kernel_mod_test.pf @@ -96,7 +96,7 @@ contains swe_test = swe_test_swe_geostr_balance, & thermal_swe = .false. ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/applications/shallow_water/unit-test/kernel/initial_swe_buoyancy_kernel_mod_test.pf b/applications/shallow_water/unit-test/kernel/initial_swe_buoyancy_kernel_mod_test.pf index 3c69d79cb..02ca8474e 100644 --- a/applications/shallow_water/unit-test/kernel/initial_swe_buoyancy_kernel_mod_test.pf +++ b/applications/shallow_water/unit-test/kernel/initial_swe_buoyancy_kernel_mod_test.pf @@ -97,7 +97,7 @@ contains swe_test = swe_test_swe_gaussian_hill, & thermal_swe = .false.) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/applications/shallow_water/unit-test/kernel/initial_swe_tracer_kernel_mod_test.pf b/applications/shallow_water/unit-test/kernel/initial_swe_tracer_kernel_mod_test.pf index 29103cf75..2e69572db 100644 --- a/applications/shallow_water/unit-test/kernel/initial_swe_tracer_kernel_mod_test.pf +++ b/applications/shallow_water/unit-test/kernel/initial_swe_tracer_kernel_mod_test.pf @@ -96,7 +96,7 @@ contains swe_test = swe_test_swe_geostr_balance, & thermal_swe = .false. ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/applications/shallow_water/unit-test/kernel/initial_swe_u_kernel_mod_test.pf b/applications/shallow_water/unit-test/kernel/initial_swe_u_kernel_mod_test.pf index 846105876..df091a7f8 100644 --- a/applications/shallow_water/unit-test/kernel/initial_swe_u_kernel_mod_test.pf +++ b/applications/shallow_water/unit-test/kernel/initial_swe_u_kernel_mod_test.pf @@ -96,7 +96,7 @@ contains swe_test = swe_test_swe_gaussian_hill, & ref_gp = 10000.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/applications/solver/rose-meta/lfric-solver/version30_31.py b/applications/solver/rose-meta/lfric-solver/version30_31.py new file mode 100644 index 000000000..ff0459300 --- /dev/null +++ b/applications/solver/rose-meta/lfric-solver/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-solver + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/solver/rose-meta/lfric-solver/versions.py b/applications/solver/rose-meta/lfric-solver/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/solver/rose-meta/lfric-solver/versions.py +++ b/applications/solver/rose-meta/lfric-solver/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/solver/rose-meta/lfric-solver/vn3.1/rose-meta.conf b/applications/solver/rose-meta/lfric-solver/vn3.1/rose-meta.conf new file mode 100644 index 000000000..e068d8a6e --- /dev/null +++ b/applications/solver/rose-meta/lfric-solver/vn3.1/rose-meta.conf @@ -0,0 +1,1109 @@ +#============================================================================== +# FINITE ELEMENT +#============================================================================== +#============================================================================== +# SYSTEM SETTINGS +#============================================================================== + +[Submission] +ns=namelist/Job/Submission +sort-key=Section-001 + +#============================================================================== +# ENVIRONMENT VARIABLES AVAILABLE TO ROSE TASK +#============================================================================== +[env] +compulsory=true + +[env=EXEC_NAME] +compulsory=true +description=Program executable name +sort-key=Panel-A01 +type=raw + +[env=OMP_NUM_THREADS] +compulsory=true +description=Number of threads for OpenMP +fail-if=this < 1 ; +range=1: +sort-key=Panel-A03 +type=integer + +[env=TOTAL_RANKS] +compulsory=true +description=Number of process ranks for a parallel run job +fail-if=this < 1 ; +range=1: +sort-key=Panel-A02 +type=integer + +#============================================================================== +# PRIMARY GLOBAL MESH +#============================================================================== +[namelist:base_mesh] +compulsory=true +description=Provides information to define the LFRic infrastructure principle mesh. +help=Lfric must use at least one mesh (prime) to run. + =This panel specifies details of the mesh and its + =configuration. +ns=namelist/Model/Mesh +sort-key=Section-A02 +title=Mesh + +[!namelist:base_mesh=f_lat] +compulsory=false +description=Latitude for F-plane + =approximation [rad]. +expression=namelist:base_mesh=f_lat_deg * source:constants_mod=PI / 180.0_r_def +help=Pre-set latitude for F-plane approximation [Radians]. The F-plane approximation + =is use to calculate the Coriolis operator, where the Coriolis parameter, f, is + =assumed to be invariant with latitude. + = +!kind=default +type=real + +[namelist:base_mesh=f_lat_deg] +compulsory=true +description=?????? +fail-if=this < -90.0 ; + =this > 90.0 ; +help=?????? + =?????? +!kind=default +range=-90.0:90.0 +sort-key=Panel-A06 +type=real + +[namelist:base_mesh=file_prefix] +compulsory=true +description=Location of 2D mesh input file(s) (prefix). +help=Input files for 2D meshes are in NetCDF file format. The mesh topologies in the file should + =be conformant to UGRID convention and must contain at least one mesh topology, the prime mesh. + = + =This variable is the file name (or path) prefix the mesh input file(s). If the meshes have + =been prepartitioned (namelist:base_mesh=prepartitioned = .true.) to match the intended + =distributed memory deployment of the application, each process rank of the run will load + =the mesh file given by: + = + = __.nc + = + =which will contain data to directly populate the required . Otherwise, a + = will be partitioned at runtime and the model will attempt to load: + = + = .nc + = + =Note: Should prepartitioned meshes be employed, the mesh input file(s) should have + = been created specifying the same number of partitions as ranks in the intended + = run. + = +sort-key=Panel-A01 +!string_length=filename +type=character +url=http://ugrid-conventions.github.io/ugrid-conventions + +[namelist:base_mesh=fplane] +compulsory=true +description=?????? +fail-if=this == true and namelist:base_mesh=geometry == "'spherical'" +help=Plane has constant f (omega) + =fplane can not be true when nature = spherical +!kind=default +sort-key=Panel-A05 +type=logical + +[namelist:base_mesh=geometry] +compulsory=true +description=The geometry on which the domain is embedded +!enumeration=true +fail-if=this == "'spherical'" and namelist:base_mesh=topology == "'fully_periodic'" and namelist:partitioning=partitioner != "'cubedsphere'" and namelist:base_mesh=prepartitioned == ".false." ; + =this == "'planar'" and namelist:partitioning=partitioner != "'planar'" and namelist:base_mesh=prepartitioned == ".false." ; +help=Along with topology this describes the domain. The geometry is the shape + =on which the domain is embedded. This is currently either 'spherical' or + ='planar'. +sort-key=Panel-A03 +value-titles=Planar, Spherical +values='planar', 'spherical' + +[namelist:base_mesh=prepartitioned] +compulsory=true +description=Load pre-partitioned local meshes +help=Input mesh files may contain global meshes whose extents are intended to cover + =the entire model domain. These may require partitioning in to a number of local + =meshes (1 per processor rank) at runtime depending on the number of ranks + =requested to run the model. + = + =Prepartitioned meshes would be beneficial in cases were the number of ranks for + =the model run seldom change. + = + =If prepartitioned meshes are not used the model will expect global meshes + =in the mesh input file to be partitioned at model runtime. + = + =Note: With increasing mesh size, at some point prepartitioned meshes may become + = necessary. + = +sort-key=Panel-A04a +trigger=namelist:partitioning: .false. ; +type=logical + +[namelist:base_mesh=prime_mesh_name] +compulsory=true +description=Tag-name for prime-mesh +help=Mesh topologies are held in UGRID conformant NetCDF files. It is + =possible that the mesh files in this format may contain more than + =one mesh topology. This tag-name identifies the mesh topology to + =use from the mesh file namelist:base_mesh=filename. +sort-key=Panel-A02 +!string_length=default +type=character + +[namelist:base_mesh=topology] +compulsory=true +description=Describes the periodicity of the domain. +!enumeration=true +fail-if=this != "'fully_periodic'" and namelist:partitioning=partitioner == "'cubedsphere'" ; +help=Together with the geometry this describes the domain. The topology is the + =periodicity of the base mesh. A mesh over the whole globe would have + =spherical geometry and fully_periodic topology, while a limited-area model + =on the sphere would have spherical geometry and non_periodic topology. +sort-key=Panel-A07 +value-titles=Fully-periodic, Non-periodic +values='fully_periodic', 'non_periodic' + +#============================================================================== +# 2D MESH EXTRUSION +#============================================================================== +[namelist:extrusion] +compulsory=true +description=Settings for the selected vertical mesh extrusion method. +help=Settings for the uniform, quadratic, geometric and DCMIP mesh extrusion + =profiles to extrude 2D to 3D mesh using non-dimensional vertical coordinate. +ns=namelist/Model/Mesh/Extrusion +sort-key=Section-A03 + +[namelist:extrusion=domain_height] +compulsory=true +description=Domain height [m] +fail-if=this < 0.0 ; +help=Height of the model domain from a flat planet surface. + =Height of planet surface taken as: + = * For Cartesian domain: 0m + = * For Spherical domain: namelist:extrusion=planet_radius +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[namelist:extrusion=method] +compulsory=true +description=Extrusion method +!enumeration=true +fail-if=this == 'um_L85_50t_35s_85km' and namelist:extrusion=number_of_layers != 85 ; + =this == 'um_L70_61t_9s_40km' and namelist:extrusion=number_of_layers != 70 ; + =this == 'um_L120_99t_21s_40km' and namelist:extrusion=number_of_layers != 120 ; + =this == 'um_L140_122t_18s_40km' and namelist:extrusion=number_of_layers != 140 ; +help=Available extrusion methods are (\f$n$ is number of layers): + =1) Uniform grid spacing (\f$\frac{k}{n}\f$); + =2) Quadratic grid spacing (\f$\frac{k}{n}^2\f$); + =3) Geometric grid spacing (\f$d\eta = \frac{(s - 1)}{(s^{n} - 1)}$) + = with stretching factor prescribed (\f$s=1.03$); + =4) DCMIP grid spacing (Ullrich et al. (2012) DCMIP documentation, Appendix F.2.) + = with flattening parameter prescribed. + =5) L38 40km UM specific spacing; + =6) L70 80km UM specific spacing; + =7) L85 85km UM specific spacing; + =8) L70 40km UM specific eta spacing; + =9) L120 40km UM specific eta spacing; + =10) L140 40km UM specific eta spacing +sort-key=Panel-A01 +value-titles=Uniform, Quadratic, Geometric, DCMIP, + = um_L38_29t_9s_40km, um_L70_50t_20s_80km, um_L85_50t_35s_85km, um_L70_61t_9s_40km, + = um_L120_99t_21s_40km, um_L140_122t_18s_40km +values='uniform', 'quadratic', 'geometric', 'dcmip', + ='um_L38_29t_9s_40km', 'um_L70_50t_20s_80km', 'um_L85_50t_35s_85km', 'um_L70_61t_9s_40km', + ='um_L120_99t_21s_40km', 'um_L140_122t_18s_40km' + +[namelist:extrusion=number_of_layers] +compulsory=true +description=Number of layers in the vertical +fail-if=this < 1 ; +help=Setting for number of layers of 3D-mesh in vertical. +!kind=default +range=1: +sort-key=Panel-A03 +type=integer + +[namelist:extrusion=planet_radius] +compulsory=true +description=[m] +fail-if=this <= 0.0 ; +help=?????? + =?????? +!kind=default +ns=namelist/Model/Planet/Properties +range=0.0: +sort-key=Panel-A02 +type=real + +#============================================================================== +# FINITE ELEMENT +#============================================================================== +[namelist:finite_element] +compulsory=true +description=Settings to define the choice of finite elements used +help=Settings to define which finite elements create the function spaces used + =in the model +ns=namelist/Model/Finite element +sort-key=Section-A01 +title=Finite element + +[namelist:finite_element=cellshape] +compulsory=true +description=The base shape of the elements forming the 2d mesh before extrusion + =into prisms in 3d +!enumeration=true +fail-if=this != "'quadrilateral'" ; +help=Current infrastructure requires that the cellshape is 'quadrilateral' +sort-key=Panel-A01 +value-titles=Triangluar, Quadrilateral +values='triangle', 'quadrilateral' + +[namelist:finite_element=coord_order] +compulsory=true +description=Order of the coordinate space. +fail-if=this < 0 ; +help=Order of the coordinate space. If 0 is chosen, this will be the continuous + =W0 space, with the order set by the element order. This option is only + =possible for certain geometries and topologies. Otherwise, this will be + =a discontinuous space. +!kind=default +range=0: +sort-key=Panel-A03 +type=integer + +[namelist:finite_element=coord_system] +compulsory=true +description=The coordinate system that will be stored in the chi coordinate + =fields used for computations throughout the model. +!enumeration=true +fail-if= +help=Select 'xyz' to run the model in global Cartesian coordinates. + =Otherwise use 'native' to run with the coordinate system native to the + =mesh being used. For instance, this will use the (alpha,beta,height) + =system with cubed-sphere meshes and the (longitude,latitude,height) system + =with spherical limited-area models. For the (alpha,beta,height) and + =(longitude,latitude,height) systems, the third coordinate field is given by + =height = radius - planet radius +sort-key=Panel-A04 +value-titles='(X,Y,Z)', 'Native' +values='xyz', 'native' + +[namelist:finite_element=element_order_h] +compulsory=true +description=The polynomial order of the set of compatible finite element in the + =horizontal +fail-if=this < 0 ; +help=This is the polynomial order of the L2 (W3) space in the horizontal + =direction, and is used to set the polynomial order for other finite element + =spaces. In most cases is equal to element_order_v. +!kind=default +range=0:9 +sort-key=Panel-A02 +type=integer + +[namelist:finite_element=element_order_v] +compulsory=true +description=The polynomial order of the set of compatible finite element in the + =vertical +fail-if=this < 0 ; +help=This is the polynomial order of the L2 (W3) space in the vertical + =direction, and is used to set the polynomial order for other finite element + =spaces. In most cases is equal to element_order_h. +!kind=default +range=0:9 +sort-key=Panel-A02 +type=integer + +[!namelist:finite_element=nqp_h_exact] +compulsory=false +expression=namelist:finite_element=element_order_h+3 +help=Number of quadrature points needed to exactly integrate a product of test & + = trial functions with a linear Jacobian in the horizontal direction +!kind=default +sort-key=Panel-A05 +type=integer + +[!namelist:finite_element=nqp_v_exact] +compulsory=false +expression=namelist:finite_element=element_order_v+3 +help=Number of quadrature points needed to exactly integrate a product of test & + = trial functions with a linear Jacobian in the vertical direction +!kind=default +sort-key=Panel-A05 +type=integer + +[namelist:finite_element=rehabilitate] +compulsory=true +description=Option to switch on rehabilitation to modify the mapping for the W3 + =space. +help=Rehabilitation is the modification of mapping for + =the W3 space and the divergence mapping so that + =the correct order of accuracy is maintained on + =non-affine elements. For affine elements it is not + =required. This is included here as in the future + =we wish to move to not rehabilitating +!kind=default +sort-key=Panel-A06 +type=logical + +[namelist:finite_element=vorticity_in_w1] +compulsory=true +description=Option to compute the vorticity in W1 (or implied W2) space +help=Compute the vorticity in W1 (or implied W2) space +!kind=default +sort-key=Panel-A07 +type=logical + +#============================================================================== +# DYNAMICS +#============================================================================== +# +#============================================================================== +# FORMULATION +#============================================================================== +[namelist:formulation] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +ns=namelist/Science/Dynamics +sort-key=Section-A07 +title=Dynamics + +[namelist:formulation=l_multigrid] +compulsory=true +description=Enable Multi-Grid +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A01 +trigger=namelist:multigrid: .true. ; +type=logical + +[namelist:formulation=use_multires_coupling] +compulsory=true +description=Enable use of multiple meshes for coupling +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A02 +trigger=namelist:multires_coupling: .true. ; +type=logical + +#============================================================================== +# SYSTEM LOGGING +#============================================================================== +[namelist:logging] +compulsory=true +ns=namelist/Job/IO/System + +[namelist:logging=log_to_rank_zero_only] +compulsory=true +description=Only log to a single rank, defined as rank zero +ns=namelist/Job/IO/System +sort-key=Panel-A02 +type=logical + +[namelist:logging=run_log_level] +compulsory=true +description=Logging level for run +!enumeration=true +help=Determines the severity of logging messages which are sent to standard + =output. Error levels are cumulative in severity: + = + = * Trace + = * Debugging + = * Information + = * Warning + = * Error + = + =e.g. Setting the log level to "Information" will mean log messages + =related to information,warnings and errors will be reported to + =standard output at runtime. + = +ns=namelist/Job/IO/System +sort-key=Panel-A01 +value-titles=Error, Warning, Information, Debugging, Trace +values='error','warning','info','debug','trace' + +[namelist:mixing] +compulsory=false +description=Subgrid mixing scheme options +help=Currently available schemes are: + =_________________________________________________________________ + =Constant viscosity: + = applied to theta & u, v, w + =_________________________________________________________________ + =Smagorinsky mixing scheme: + = applied to theta, moisture (water vapour and cloud liquid), + = u, v and w +!kind=default +ns=namelist/Science/Dynamics/Mixing +sort-key=Section-A05 + +[namelist:mixing=method] +compulsory=true +description=Smagorinsky subgrid mixing scheme option +!enumeration=true +help=Options for Smagorinsky subgrid mixing scheme: + =_________________________________________________________________ + =3D Smag + = Smagorinsky mixing scheme applied in horizontal and vertical. + =_________________________________________________________________ + =2D Smag + 1D BL + = Smagorinsky mixing scheme applied in horizontal. + = 1D BL scheme used in the vertical. + =_________________________________________________________________ + =Blended scheme + = Blended BL-Smagorinsky diffusion coefficient used for + = subgrid mixing in horizontal and vertical. + = + = WARNING: This option currently does not conserve energy and as + = a result may be unstable. +sort-key=Panel-A05 +value-titles=3D Smagorinsky, 2D Smagorinsky + 1D BL, Blended scheme +values='3d_smag', '2d_smag', 'blending' + +[namelist:mixing=mix_factor] +compulsory=true +description=Smagorinsky mixing length constant +help=Smagorinsky mixing length constant, typical value is 0.2 +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:mixing=smagorinsky] +compulsory=true +description=Enable Smagorinsky mixing +help=Apply Smagorinsky mixing to theta, + = moisture (water vapour and cloud liquid), u, v and w + = + = NOTE: As in the current UM implementation of Smagorinsky mixing, + = the stress terms have been implemented purely as diffusion terms. + = This results in a missing term, as described in UMDP28. + = + = WARNING: Current implementation assumes a Cartesian mesh. +!kind=default +sort-key=Panel-A03 +trigger=namelist:mixing=method: .true. ; + =namelist:mixing=mix_factor: .true. ; +type=logical + +#============================================================================== +# MIXING: Namelist Members +#============================================================================== +[namelist:mixing=viscosity] +compulsory=true +description=?????? +help=Apply constant viscosity to theta & u, v, w +!kind=default +sort-key=Panel-A01 +type=logical + +[namelist:mixing=viscosity_mu] +compulsory=true +description=?????? +help=Viscosity constant to use +!kind=default +sort-key=Panel-A02 +type=real + +#================= +# Multigrid Mesh = +#================= +#============================================================================== +# MULTIGRID +#============================================================================== +[namelist:multigrid] +compulsory=true +description=?????? +help=?????? + =?????? +ns=namelist/Science/Dynamics/multigrid +sort-key=Section-A06 +title=Multi-grid + +[namelist:multigrid=chain_mesh_tags] +!bounds=namelist:multigrid=multigrid_chain_nitems +compulsory=true +description=Meshes for function space chain. +fail-if=len(this) != namelist:multigrid=multigrid_chain_nitems ; +help=This is an ordered list of mesh names as loaded from the mesh + =input file. It is expected that the mesh input file will contain + =the correct intergrid maps betwen subsequent meshes in the chain. + = +length=: +sort-key=Panel-A04 +!string_length=default +type=character + +[namelist:multigrid=multigrid_chain_nitems] +compulsory=true +description=Number of items in multigrid function space chain +fail-if=this < 1 ; +help=?????? + =?????? +!kind=default +range=1: +sort-key=Panel-A02 +type=integer + +[namelist:multigrid=n_coarsesmooth] +compulsory=false +type=integer + +[namelist:multigrid=n_postsmooth] +compulsory=false +type=integer + +[namelist:multigrid=n_presmooth] +compulsory=false +type=integer + +[namelist:multigrid=smooth_relaxation] +compulsory=false +type=real + +#============================================================================== +# MULTIRESOLUTION COUPLING (e.g. Physics-Dynamics-Chemistry) +#============================================================================== +[namelist:multires_coupling] +compulsory=false +description=This namelist specifies options for running different model + =components on different meshes +help=This namelist provides different modes and meshes for running the coupling + =miniapp +ns=namelist/Science/Dynamics/multires_coupling +sort-key=Section-A07 +title=Multires-Coupling + +[namelist:multires_coupling=dynamics_mesh_name] +compulsory=false +description=Tag-name for mesh used by dyanamics +help=This is the mesh on which the dynamical core is run +sort-key=Panel-A02 +!string_length=default +type=character + +[namelist:multires_coupling=multires_coupling_mesh_tags] +compulsory=false +description=List of mesh tag-names for the meshes used in the coupling miniapp +help=This is an ordered list of mesh names as loaded from the mesh + =input file for the coupling miniapp. It is expected that the mesh + =input file will contain the required intergrid maps between the meshes +length=: +sort-key=Panel-A01 +!string_length=default +type=character + +[namelist:multires_coupling=multires_coupling_mode] +compulsory=false +description=Describes the mode in which the coupling miniapp will be run +!enumeration=true +help=Test - a simple test case to test miniapp capabilities + =Jnr-Snr - dynamics and physics at a fine resolution coupled + =with dynamics, physics and chemistry at a coarse resolution + =Physics-Dynamics - physics and dynamics run at different resolutions + =and coupled together +sort-key=Panel-A05 +value-titles=Test, Jnr-Snr, Physics-Dynamics +values='test', 'jnr_snr', 'physics_dynamics' + +[namelist:multires_coupling=output_mesh_name] +compulsory=false +description=Tag-name for mesh used for outputting diagnostics +help=This is the mesh on which fields will be output. Any fields not native to + =this mesh will be mapped to this mesh for outputting. +sort-key=Panel-A03 +!string_length=default +type=character + +[namelist:multires_coupling=physics_mesh_name] +compulsory=false +description=Tag-name for mesh used by physics +help=This is the mesh on which the physics parametrisations are run +sort-key=Panel-A04 +!string_length=default +type=character + +#============================================================================== +# GLOBAL MESH PARTITIONING +#============================================================================== +[namelist:partitioning] +compulsory=true +description=Global mesh panel partitioning. +help=For parallel computing, the 2D global mesh is divided up into partitions. + =Each process rank runs an instance of the model on one partition. The + =partition decompostion is specified on a `per panel` basis. + =i.e. The cubedsphere has six panels; the planar mesh has one panel. +ns=namelist/Model/Mesh/Partitioning +sort-key=Section-A02 + +[namelist:partitioning=coarsen_multigrid_tiles] +compulsory=false +description=Reduce x and y tile sizes by a factor of 2 in each multigrid level +help=Enables using larger tiles at higher resolution levels by automatically + =reducing tile sizes in coarser levels, which can improve performance. +sort-key=Panel-A10 +type=logical + +[namelist:partitioning=generate_inner_halos] +compulsory=true +description=Generate inner halo regions +help=In order to overlap comms & compute, the owned cells are reordered + =so that they consist of a number of layers of inner halos. These owned + =cells correspond to the halo cells on neighbouring MPI regions. +sort-key=Panel-A05 +type=logical + +[namelist:partitioning=inner_halo_tiles] +compulsory=false +description=Tile inner halos separately from partition interior. +help=Tiling inner halos separately from the partition interior guarantees + =that tiles never cross the boundary between interior and inner halo, + =which can be useful when overlapping communication and computation. +sort-key=Panel-A08 +type=logical + +[namelist:partitioning=max_tiled_multigrid_level] +compulsory=false +description=Coarsest multigrid level to be tiled +help=Revert to 1x1 tiling (equivalent to colouring) for multigrid levels + =above this threshold (level 1 has highest resolution); tiling is + =typically more beneficial for higher resolutions. +range=1: +sort-key=Panel-A09 +type=integer + +[namelist:partitioning=panel_decomposition] +compulsory=true +description=Panel partition decomposition +!enumeration=true +help=Partitioner will attempt to generate partitioned panels based + =on the given enumeration choices: + = + = * auto: Decompose domain as close to square decompositions. + = * row: Single row of partitions. + = * column: Single column of partitions. + = * custom: x/y decompositions explicitly requested using + = namelist:partitioning=panel_xproc, + = namelist:partitioning=panel_yproc. + = * auto_nonuniform: As auto but allow columns of partitions + = of differing heights. + = * guided_nonuniform: Partition into columns according to + = namelist:partitioning=panel_xproc but of different heights + = +!kind=default +sort-key=Panel-A01 +trigger=namelist:partitioning=panel_xproc: this == "'custom'" or this == "'guided_nonuniform'" ; + =namelist:partitioning=panel_yproc: this == "'custom'" ; +value-titles=Auto, Single row, Single column, Custom, Auto nonuniform, Guided nonuniform +values='auto', 'row', 'column', 'custom', 'auto_nonuniform', 'guided_nonuniform' + +[namelist:partitioning=panel_xproc] +compulsory=true +description=Panel partitions in x-direction +fail-if=this < 1 ; + =(env=TOTAL_RANKS == 1) and (this != 1) ; + =(env=TOTAL_RANKS != 1) and (namelist:base_mesh=geometry=="'spherical'") and ( this*namelist:partitioning=panel_yproc != env=TOTAL_RANKS/6 ) ; + =(env=TOTAL_RANKS != 1) and (namelist:base_mesh=geometry=="'planar'") and ( this*namelist:partitioning=panel_yproc != env=TOTAL_RANKS ) ; +help=Number of partitions to generate across the x-direction of a panel of the mesh +!kind=default +range=1: +sort-key=Panel-A02 +type=integer + +[namelist:partitioning=panel_yproc] +compulsory=true +description=Panel partitions in y-direction +fail-if=this < 1 ; + =(env=TOTAL_RANKS == 1) and (this != 1) ; + =(env=TOTAL_RANKS != 1) and (namelist:base_mesh=geometry=="'spherical'") and ( this*namelist:partitioning=panel_xproc != env=TOTAL_RANKS/6 ) ; + =(env=TOTAL_RANKS != 1) and (namelist:base_mesh=geometry=="'planar'") and ( this*namelist:partitioning=panel_xproc != env=TOTAL_RANKS ) ; +help=Number of partitions to generate across the y-direction of a panel of the mesh +!kind=default +range=1: +sort-key=Panel-A03 +type=integer + +[namelist:partitioning=partitioner] +compulsory=true +description=?????? +!enumeration=true +fail-if=this == "'cubedsphere'" and not ( namelist:base_mesh=geometry == "'spherical'" and namelist:base_mesh=topology == "'fully_periodic'" ); + =this == "'cubedsphere'" and not ( env=TOTAL_RANKS % 6 == 0 or env=TOTAL_RANKS == 1 ) ; +help=?????? + =?????? +sort-key=Panel-A04 +value-titles=Planar, Cubedsphere +values='planar', 'cubedsphere' + +[namelist:partitioning=tile_size_x] +compulsory=false +description=Tile size (number of cells) in x-direction +help=Tiling reorders computation of cells in the horizontal mesh to maximise + =processor cache reuse. It is currently only available for partitioned + =meshes and where mesh partitions have a rectangular shape. Tiles sizes + =along partition borders are automatically adjusted to fit, but sizes that + =are larger than partition dimensions are not accepted. +range=1: +sort-key=Panel-A06 +type=integer + +[namelist:partitioning=tile_size_y] +compulsory=false +description=Tile size (number of cells) in y-direction +help=Tiling reorders computation of cells in the horizontal mesh to maximise + =processor cache reuse. It is currently only available for partitioned + =meshes and where mesh partitions have a rectangular shape. Tiles sizes + =along partition borders are automatically adjusted to fit, but sizes that + =are larger than partition dimensions are not accepted. +range=1: +sort-key=Panel-A07 +type=integer + +#============================================================================== +# PLANET +#============================================================================== +[namelist:planet] +compulsory=true +description=?????? +help=?????? + =?????? +ns=namelist/Model/Planet +sort-key=Section-A03 + +[namelist:planet=cp] +compulsory=true +description=[J/(kg K)] +fail-if=this <= 0.0 ; +help=Specific heat of dry air at constant pressure [J/(kg K)] +!kind=default +ns=namelist/Model/Planet/Properties +range=0.0: +sort-key=Panel-A05 +type=real + +[!namelist:planet=cv] +compulsory=false +expression=namelist:planet=cp - namelist:planet=rd +help=Specific heat of dry air at constant volume [J/(kg K)] +!kind=default +type=real + +[!namelist:planet=epsilon] +compulsory=false +description=Ratio of molecular weights: dry air / water +expression=namelist:planet=rd / source:driver_water_constants_mod=gas_constant_h2o +help=Molecular weight of water divided by molecular weight of dry air. + =[dimensionless] +!kind=default +type=real + +[namelist:planet=gravity] +compulsory=true +description=[m/(s^2)] +fail-if=this <= 0.0 ; +help=Surface equatorial value of gravity [m/s^2] +!kind=default +ns=namelist/Model/Planet/Properties +range=0.0: +sort-key=Panel-A01 +type=real + +[!namelist:planet=kappa] +compulsory=false +expression=namelist:planet=rd / namelist:planet=cp +help=Ratio of Rd and Cp [dimensionless] +!kind=default +type=real + +[namelist:planet=omega] +compulsory=true +description=[units?] +help=?????? + =?????? +!kind=default +ns=namelist/Model/Planet/Properties +sort-key=Panel-A03 +type=real + +[namelist:planet=p_zero] +compulsory=true +description=[Pa] +help=Reference surface pressure [Pa] +!kind=default +ns=namelist/Model/Planet/Properties +sort-key=Panel-A06 +type=real + +[namelist:planet=rd] +compulsory=true +description=[J/(kg K)] +help=Gas constant for dry air [J/(kg K)] +!kind=default +ns=namelist/Model/Planet/Properties +sort-key=Panel-A04 +type=real + +[!namelist:planet=recip_epsilon] +compulsory=false +expression=source:driver_water_constants_mod=gas_constant_h2o / namelist:planet=rd +help=Reciprocal of ratio molecular mass of water to dry air. + =[dimensionless] +!kind=default +type=real + +[!namelist:planet=scaled_omega] +compulsory=false +expression=namelist:planet=omega * namelist:planet=scaling_factor +help=?????? + =?????? +!kind=default +type=real + +[!namelist:planet=scaled_radius] +compulsory=false +expression=namelist:extrusion=planet_radius / namelist:planet=scaling_factor +help=?????? + =?????? +!kind=default +type=real + +[namelist:planet=scaling_factor] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +sort-key=Panel-A07 +type=real + +#============================================================================== +# MASS MATRIX SOLVER +#============================================================================== +[namelist:solver] +compulsory=true +description=?????? +help=This namelist is for using iteratives solvers for the inversion of mass matrices +ns=namelist/Science/Dynamics/Mass Matrix Solver +sort-key=Section-A04 + +[namelist:solver=fail_on_non_converged] +compulsory=true +description=Cause the solver to return an error if the maximum number of iterations are reached and + =residual has not been reduced below the desired tolerance otherwise the solver will exit even + =if it has not converged. If monitor_convergence is set to false then this setting has no effect +help=Return an error if solver fails to converge +sort-key=Panel-A07 +type=logical + +[namelist:solver=gcrk] +compulsory=true +description=?????? +help=Dimension of the approximate Krylov subspace. + =In other words, it is the number of potential + =residual vectors to calculate at each + =iteration of the solver. +!kind=default +sort-key=Panel-A05 +type=integer + +[namelist:solver=jacobi_relaxation] +compulsory=true +description=?????? +help=Relaxtion factor to use in the Jacobi solver +!kind=default +sort-key=Panel-A11 +type=real + +[namelist:solver=maximum_iterations] +compulsory=true +description=?????? +fail-if=this < 1 ; +help=Iteration limit for solver +!kind=default +range=1: +sort-key=Panel-A02 +type=integer + +[namelist:solver=method] +compulsory=true +description=?????? +!enumeration=true +help=?????? + =?????? +sort-key=Panel-A01 +trigger=namelist:solver=jacobi_relaxation: this == "'jacobi'"; +value-titles=biconjugate gradient stabilized, + =conjugate gradient, + =generalized conjugate residual, + =generalized minimal residual, + =flexible generalized minimal residual, + =precondition only, + =jacobi +values='bicgstab', 'cg', 'gcr', 'gmres', 'fgmres', 'prec_only', 'jacobi' + +[namelist:solver=monitor_convergence] +compulsory=true +description=Computes and prints out convergence information for the iterative solver and if the + =error has been reduced below the tolerance then the solver will exit. If set to false + =the solver will always perform the maximum number of iterations before exiting +help=Monitor convergence of the iterative mass matrix solver +sort-key=Panel-A06 +trigger=namelist:solver=fail_on_non_converged: .true.; +type=logical + +[namelist:solver=preconditioner] +compulsory=true +description=?????? +!enumeration=true +help=?????? + =?????? +sort-key=Panel-A04 +value-titles=None, Diagonal +values='none', 'diagonal' + +[namelist:solver=tolerance] +compulsory=true +description=?????? +help=Relative tolerance of solver +!kind=default +sort-key=Panel-A03 +type=real + +#============================================================================== +# SUBGRID +#============================================================================== +[namelist:subgrid] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Science/Dynamics/Subgrid +sort-key=Section-A09 + +[namelist:subgrid=dep_pt_stencil_extent] +compulsory=true +description=?????? +fail-if=this < 1 ; +help=?????? + =?????? +!kind=default +range=1: +sort-key=Panel-A02 +type=integer + +#============================================================================== +# TRANSPORT +#============================================================================== +[namelist:transport] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Science/Dynamics/Transport +sort-key=Section-A10 + +[namelist:transport=consistent_metric] +compulsory=true +description=?????? +fail-if= +help=Compute metric terms with the advection scheme +!kind=default +sort-key=Panel-A05 +trigger= +type=logical + +[namelist:transport=enforce_monotonicity] +compulsory=true +description=?????? +fail-if= +help=Enforce monotonicity with Method of Lines advection +!kind=default +sort-key=Panel-A06 +# This option should only be triggered if transport scheme is method_of_lines +trigger= +type=logical + +[namelist:transport=fv_advective_order] +compulsory=true +description=?????? +fail-if= +help=?????? + =?????? +!kind=default +!range= +sort-key=Panel-A04 +# This option should only be triggered if transport scheme is method_of_lines +trigger= +type=integer + +[namelist:transport=fv_flux_order] +compulsory=true +description=?????? +fail-if= +help=?????? + =?????? +!kind=default +!range= +sort-key=Panel-A03 +trigger= +type=integer + +[namelist:transport=oned_reconstruction] +compulsory=true +description=Control use of 1D or 2D polynomial reconstruction of tracer fields + =for the method of lines advection scheme +fail-if= +help=Use 1D or 2D horizontal reconstruction +!kind=default +sort-key=Panel-A07 +# This option should only be triggered if transport scheme is method_of_lines +trigger= +type=logical + +[namelist:transport=operators] +compulsory=false +description=?????? +!enumeration=true +fail-if= +help=?????? + =?????? +sort-key=Panel-A02 +# This option should only be triggered if transport scheme is method_of_lines +trigger= +value-titles=Finite volume, Finite element +values='fv', 'fem' + +[namelist:transport=scheme] +compulsory=true +description=?????? +!enumeration=true +fail-if= +help=Method of lines : Uses Runge-Kutta SSP3 for time integration of fluxes + =Cosmic horizontal : Cosmic transport scheme in the horizontal + =Cosmic YZ (biperiodic) : Cosmic transport scheme for a Y-Z slice of (biperiodic mesh) + =Cosmic 3D : 3D Cosmic transport for biperiodic and cubed-sphere mesh +sort-key=Panel-A01 +value-titles=Method of lines, Cosmic horizontal, Cosmic YZ (biperiodic), Cosmic 3D +# = namelist:transport=operators: this == "'method_of_lines'" ; +# = namelist:transport=fv_advective_order: this == "'method_of_lines'" ; +# = namelist:transport=enforce_monotonicity: this == "'method_of_lines'" ; +#trigger= namelist:subgrid: this != "'method_of_lines'" ; +# = namelist:biperiodic_deppt: this != "'method_of_lines'" ; +# = namelist:transport=operators: this == "'method_of_lines'" ; +# = namelist:transport=fv_advective_order: this == "'method_of_lines'" ; +# = namelist:transport=enforce_monotonicity: this == "'method_of_lines'" ; +# = namelist:transport=oned_reconstruction: this == "'method_of_lines'" ; +values='method_of_lines', 'horz_cosmic', 'yz_bip_cosmic', 'cosmic_3D' diff --git a/applications/solver/source/solver.F90 b/applications/solver/source/solver.F90 index 466603082..197472851 100644 --- a/applications/solver/source/solver.F90 +++ b/applications/solver/source/solver.F90 @@ -14,7 +14,7 @@ program solver use add_mesh_map_mod, only: assign_mesh_maps use constants_mod, only: i_def, r_def, PRECISION_REAL, str_def use convert_to_upper_mod, only: convert_to_upper - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use create_mesh_mod, only: create_mesh, create_extrusion use driver_collections_mod, only: init_collections, final_collections use driver_config_mod, only: init_config, final_config @@ -86,7 +86,7 @@ program solver character(str_def) :: prime_mesh_name - integer(i_def) :: stencil_depth + integer(i_def) :: stencil_depth(1) integer(i_def) :: geometry integer(i_def) :: method integer(i_def) :: number_of_layers @@ -102,6 +102,8 @@ program solver ! Driver layer init !----------------------------------------------------------------------------- + call parse_command_line( filename ) + ! Initialise MPI communicatios and get a valid communicator call create_comm(comm) @@ -114,7 +116,6 @@ program solver total_ranks = global_mpi%get_comm_size() local_rank = global_mpi%get_comm_rank() - call get_initial_filename( filename ) call configuration%initialise( program_name, table_len=10 ) call init_config( filename, solver_required_namelists, & configuration ) diff --git a/applications/transport/example/configuration.nml b/applications/transport/example/configuration.nml index e240dc3ad..297bf9328 100644 --- a/applications/transport/example/configuration.nml +++ b/applications/transport/example/configuration.nml @@ -98,6 +98,7 @@ y2=0.0, &transport adjust_theta=.false. adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj='upwind' diff --git a/applications/transport/example/iodef.xml b/applications/transport/example/iodef.xml index b09d984f5..19554bb49 100644 --- a/applications/transport/example/iodef.xml +++ b/applications/transport/example/iodef.xml @@ -189,7 +189,7 @@ performance - 1.0 + 1.0 diff --git a/applications/transport/rose-meta/lfric-transport/version30_31.py b/applications/transport/rose-meta/lfric-transport/version30_31.py new file mode 100644 index 000000000..f024bde13 --- /dev/null +++ b/applications/transport/rose-meta/lfric-transport/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-transport + # Blank Upgrade Macro + return config, self.reports diff --git a/applications/transport/rose-meta/lfric-transport/versions.py b/applications/transport/rose-meta/lfric-transport/versions.py index 152c043d0..01798ad2b 100644 --- a/applications/transport/rose-meta/lfric-transport/versions.py +++ b/applications/transport/rose-meta/lfric-transport/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/applications/transport/rose-meta/lfric-transport/vn3.1/rose-meta.conf b/applications/transport/rose-meta/lfric-transport/vn3.1/rose-meta.conf new file mode 100644 index 000000000..7f6586436 --- /dev/null +++ b/applications/transport/rose-meta/lfric-transport/vn3.1/rose-meta.conf @@ -0,0 +1,125 @@ +import=lfric-gungho/vn3.1 + +#============================================================================== +# INITIAL TRACER FIELD +#============================================================================== +[namelist:initial_tracer_field] +compulsory=true +description=Namelist options to set up the tracer fields in the transport miniapp. +help=?????? + =?????? +!kind=default +ns=namelist/Job/Initial conditions/Tracer +sort-key=Section-A03 + +[namelist:initial_tracer_field=field_background] +compulsory=true +description=Background value of the tracer field. +fail-if=this < 0.0 ; +help=Background value of tracer. The tracer value away from the + =set tracer function, usually the minimum tracer value. +!kind=default +range=0.0: +sort-key=Panel-A03 +type=real + +[namelist:initial_tracer_field=field_max] +compulsory=true +description=Maximum value of tracer field function. +fail-if=this < 0.0 ; +help=The maximum value of the tracer field function. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[namelist:initial_tracer_field=r1] +compulsory=true +description=Radius of initial tracer field function. +fail-if=this < 0.0 ; +help=Radius for one of the pair of initial tracer field functions + =Biperiodic domain: in metres. + =Cubed sphere domain: in radians. +!kind=default +range=0.0: +sort-key=Panel-A04 +type=real + +[namelist:initial_tracer_field=r2] +compulsory=true +description=Radius of second initial tracer field function. +fail-if= +help=Radius parameter for the second of the pair of initial tracer field functions (see r1) +!kind=default +!range= +sort-key=Panel-A08 +trigger= +type=real + +[namelist:initial_tracer_field=x1] +compulsory=true +description=Centre in long/x of tracer field function. +help=Position for one of the pair of initial tracer field functions + =Biperiodic domain: centre of the function given in terms of metres in the chi1 direction. + =Cubed sphere domain: longitudinal position of the centre of the function (a value between 0 and \f$2\pi\f$). +!kind=default +sort-key=Panel-A05 +trigger= +type=real + +[namelist:initial_tracer_field=x2] +compulsory=true +description=Centre in long/x of second tracer field function. +fail-if= +help=Position parameter for the second of the pair of initial tracer field functions (see x1) +!kind=default +!range= +sort-key=Panel-A09 +trigger= +type=real + +[namelist:initial_tracer_field=y1] +compulsory=true +description=Centre in lat/y of tracer field function. +fail-if= +help=Position for one of the pair of initial tracer field functions + =Biperiodic domain: centre of the function given in terms of metres in the chi2 direction. + =Cubed sphere domain: latitudinal position of the centre of the function (a value between \f$-\pi/2\f$ and \f$\pi/2\f$). +!kind=default +!range= +sort-key=Panel-A06 +trigger= +type=real + +[namelist:initial_tracer_field=y2] +compulsory=true +description=Centre in lat/y of second tracer field function. +fail-if= +help=Position parameter for the second of the pair of initial tracer field functions (see y1) +!kind=default +!range= +sort-key=Panel-A10 +trigger= +type=real + +[namelist:initial_tracer_field=z1] +compulsory=true +description=Centre in height of tracer field function. +fail-if= +help=Centre height position for one of the pair of initial tracer field functions +!kind=default +!range= +sort-key=Panel-A07 +trigger= +type=real + +[namelist:initial_tracer_field=z2] +compulsory=true +description=Centre in height of second tracer field function. +fail-if= +help=Centre height position for one of the pair of initial tracer field functions +!kind=default +!range= +sort-key=Panel-A11 +trigger= +type=real diff --git a/applications/transport/source/algorithm/mass_conservation_alg_mod.x90 b/applications/transport/source/algorithm/mass_conservation_alg_mod.x90 index 9a023bc3a..288ab8f05 100644 --- a/applications/transport/source/algorithm/mass_conservation_alg_mod.x90 +++ b/applications/transport/source/algorithm/mass_conservation_alg_mod.x90 @@ -26,8 +26,8 @@ module mass_conservation_alg_mod use mesh_collection_mod, only: mesh_collection use mesh_mod, only: mesh_type use mr_indices_mod, only: nummr - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -62,9 +62,10 @@ contains type(field_type) :: coarse_rho_d, rho_X, aerosol_shifted real(kind=r_def) :: total_dry_mass, total_water_mass real(kind=r_def) :: total_w3_aerosol_mass, total_wt_aerosol_mass + integer(tik) :: id - if ( subroutine_timers ) call timer( 'mass_conservation' ) + if ( LPROF ) call start_timing( id, 'mass_conservation' ) mesh => rho_d%get_mesh() @@ -126,7 +127,7 @@ contains nullify( coarse_mesh, w3_sh_fs, shifted_mesh ) end if - if ( subroutine_timers ) call timer( 'mass_conservation' ) + if ( LPROF ) call stop_timing( id, 'mass_conservation' ) end subroutine mass_conservation diff --git a/applications/transport/source/driver/transport_driver_mod.f90 b/applications/transport/source/driver/transport_driver_mod.f90 index 2f9d4361d..5cfc4f465 100644 --- a/applications/transport/source/driver/transport_driver_mod.f90 +++ b/applications/transport/source/driver/transport_driver_mod.f90 @@ -51,7 +51,8 @@ module transport_driver_mod use mr_indices_mod, only: nummr use namelist_mod, only: namelist_type use runtime_constants_mod, only: create_runtime_constants - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_init_fields_alg_mod, only: transport_init_fields_alg use transport_control_alg_mod, only: transport_prerun_setup, & transport_init, transport_step, & @@ -125,6 +126,7 @@ subroutine initialise_transport( program_name, modeldb ) character(len=str_def), allocatable :: chain_mesh_tags(:) character(len=str_def) :: aerosol_mesh_name character(len=str_def) :: prime_mesh_name + integer(kind=i_def), allocatable :: stencil_depths(:) logical(kind=l_def) :: use_multires_coupling logical(kind=l_def) :: l_multigrid @@ -132,7 +134,6 @@ subroutine initialise_transport( program_name, modeldb ) logical(kind=l_def) :: apply_partition_check integer(kind=i_def) :: geometry - integer(kind=i_def) :: stencil_depth real(kind=r_def) :: domain_bottom real(kind=r_def) :: domain_height real(kind=r_def) :: scaled_radius @@ -283,7 +284,11 @@ subroutine initialise_transport( program_name, modeldb ) ! 1.3a Initialise prime/2d meshes ! --------------------------------------------------------- - stencil_depth = get_required_stencil_depth() + allocate(stencil_depths(num_base_meshes)) + call get_required_stencil_depth( & + stencil_depths, base_mesh_names, modeldb%configuration & + ) + apply_partition_check = .false. if ( .not. prepartitioned .and. & ( l_multigrid .or. use_multires_coupling ) ) then @@ -294,7 +299,7 @@ subroutine initialise_transport( program_name, modeldb ) modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & base_mesh_names, & - extrusion, stencil_depth, & + extrusion, stencil_depths, & apply_partition_check ) call create_mesh( base_mesh_names, extrusion_2d, & @@ -446,11 +451,20 @@ subroutine initialise_transport( program_name, modeldb ) end if - if (allocated(base_mesh_names)) deallocate(base_mesh_names) - if (allocated(meshes_to_shift)) deallocate(meshes_to_shift) - if (allocated(meshes_to_double)) deallocate(meshes_to_double) - + if (allocated(base_mesh_names)) deallocate(base_mesh_names) + if (allocated(meshes_to_shift)) deallocate(meshes_to_shift) + if (allocated(meshes_to_double)) deallocate(meshes_to_double) + if (allocated(twod_names)) deallocate(twod_names) + if (allocated(shifted_names)) deallocate(shifted_names) + if (allocated(double_names)) deallocate(double_names) + if (allocated(extrusion)) deallocate(extrusion) + if (allocated(extrusion_2d)) deallocate(extrusion_2d) + if (allocated(extrusion_shifted)) deallocate(extrusion_shifted) + if (allocated(extrusion_double)) deallocate(extrusion_double) + if (allocated(chain_mesh_tags)) deallocate(chain_mesh_tags) + if (allocated(stencil_depths)) deallocate(stencil_depths) if (allocated(extra_io_mesh_names)) deallocate(extra_io_mesh_names) + nullify(chi_inventory, panel_id_inventory, mesh, aerosol_mesh) end subroutine initialise_transport @@ -464,7 +478,6 @@ subroutine step_transport( model_clock ) use formulation_config_mod, only: use_multires_coupling use io_config_mod, only: diagnostic_frequency, & nodal_output_on_w3, & - subroutine_timers, & write_diag use multires_coupling_config_mod, only: aerosol_mesh_name use sci_field_minmax_alg_mod, only: log_field_minmax @@ -475,6 +488,7 @@ subroutine step_transport( model_clock ) type(mesh_type), pointer :: mesh type(mesh_type), pointer :: aerosol_mesh + integer(tik) :: id call log_event( 'Miniapp will run with default precision set as:', LOG_LEVEL_INFO ) write(log_scratch_space, '(I1)') kind(1.0_r_def) @@ -504,7 +518,7 @@ subroutine step_transport( model_clock ) 'Start of timestep ', model_clock%get_step() call log_event( log_scratch_space, LOG_LEVEL_INFO ) - if ( subroutine_timers ) call timer( 'transport step' ) + if ( LPROF ) call start_timing( id, 'transport_step' ) call transport_step( model_clock, & wind, density, theta, tracer_con, & @@ -512,7 +526,7 @@ subroutine step_transport( model_clock ) w3_aerosol, wt_aerosol, aerosol_wind, & nummr_to_transport ) - if ( subroutine_timers ) call timer( 'transport step' ) + if ( LPROF ) call stop_timing( id, 'transport_step' ) ! Write out conservation diagnostics call mass_conservation( model_clock%get_step(), density, mr, & diff --git a/applications/transport/source/kernel/set_tracer_field_kernel_mod.F90 b/applications/transport/source/kernel/set_tracer_field_kernel_mod.F90 index 7e06eaea4..e6cd86ab4 100644 --- a/applications/transport/source/kernel/set_tracer_field_kernel_mod.F90 +++ b/applications/transport/source/kernel/set_tracer_field_kernel_mod.F90 @@ -18,10 +18,14 @@ module set_tracer_field_kernel_mod GH_QUADRATURE_XYoZ use fs_continuity_mod, only : Wchi use constants_mod, only : r_def, i_def - use idealised_config_mod, only : test use kernel_mod, only : kernel_type use log_mod, only : log_event, LOG_LEVEL_ERROR + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use idealised_config_mod, only: test + use planet_config_mod, only: scaled_radius + implicit none private @@ -148,7 +152,9 @@ subroutine set_tracer_field_code(nlayers, tracer, & chi_2_e(df1) = chi_2( map_chi(df1) + k ) chi_3_e(df1) = chi_3( map_chi(df1) + k ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, & jac, dj) diff --git a/applications/transport/source/transport.f90 b/applications/transport/source/transport.f90 index 5530b1cba..54369eee1 100644 --- a/applications/transport/source/transport.f90 +++ b/applications/transport/source/transport.f90 @@ -8,7 +8,7 @@ !> run_transport() and finalise_transport(). program transport - use cli_mod, only: get_initial_filename + use cli_mod, only: parse_command_line use constants_mod, only: i_def, r_def use driver_collections_mod, only: init_collections, final_collections use driver_comm_mod, only: init_comm, final_comm @@ -16,13 +16,14 @@ program transport use driver_log_mod, only: init_logger, final_logger use driver_modeldb_mod, only: modeldb_type use driver_time_mod, only: init_time, final_time - use driver_timer_mod, only: init_timers, final_timers use lfric_mpi_mod, only: global_mpi use log_mod, only: log_event, & log_level_trace, & log_scratch_space use namelist_collection_mod, only: namelist_collection_type - + use namelist_mod, only: namelist_type + use timing_mod, only: init_timing, final_timing + use io_config_mod, only: timer_output_path use transport_mod, only: transport_required_namelists use transport_driver_mod, only: initialise_transport, & step_transport, & @@ -33,11 +34,14 @@ program transport type(modeldb_type) :: modeldb character(*), parameter :: program_name = "transport" character(:), allocatable :: filename + type(namelist_type), pointer :: io_nml + logical :: lsubroutine_timers + + call parse_command_line( filename ) call modeldb%configuration%initialise( program_name, table_len=10 ) modeldb%mpi => global_mpi call init_comm( program_name, modeldb ) - call get_initial_filename( filename ) call init_config( filename, transport_required_namelists, & modeldb%configuration ) call init_logger( modeldb%mpi%get_comm(), program_name ) @@ -49,7 +53,10 @@ program transport write(log_scratch_space, '(" i_def kind = ", I0)') kind(1_i_def) call log_event( log_scratch_space , log_level_trace ) - call init_timers( program_name ) + io_nml => modeldb%configuration%get_namelist('io') + call io_nml%get_value('subroutine_timers', lsubroutine_timers) + call init_timing( modeldb%mpi%get_comm(), lsubroutine_timers, program_name, timer_output_path ) + nullify( io_nml ) call init_collections() call init_time( modeldb ) deallocate( filename ) @@ -67,7 +74,7 @@ program transport call final_time( modeldb ) call final_collections() - call final_timers( program_name ) + call final_timing( program_name ) call final_logger( program_name ) call final_config() call final_comm( modeldb ) diff --git a/applications/transport/unit-test/kernel/initial_tracer_field_sample_kernel_mod_test.pf b/applications/transport/unit-test/kernel/initial_tracer_field_sample_kernel_mod_test.pf index 7fcd8dc18..851d10191 100644 --- a/applications/transport/unit-test/kernel/initial_tracer_field_sample_kernel_mod_test.pf +++ b/applications/transport/unit-test/kernel/initial_tracer_field_sample_kernel_mod_test.pf @@ -82,7 +82,7 @@ contains f_lon_deg=0.0_r_def, perturb_init=.false., & perturb_magnitude=0, perturb_seed=0 ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/applications/transport/unit-test/kernel/set_tracer_field_kernel_mod_test.pf b/applications/transport/unit-test/kernel/set_tracer_field_kernel_mod_test.pf index 04e00da19..12e83028f 100644 --- a/applications/transport/unit-test/kernel/set_tracer_field_kernel_mod_test.pf +++ b/applications/transport/unit-test/kernel/set_tracer_field_kernel_mod_test.pf @@ -103,7 +103,7 @@ contains p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/build/extract/extract_physics.mk b/build/extract/extract_physics.mk index a4df2535b..7e43cd1b0 100644 --- a/build/extract/extract_physics.mk +++ b/build/extract/extract_physics.mk @@ -20,7 +20,4 @@ extract: # Retrieve and preprocess the UKCA and CASIM code - python $(APPS_ROOT_DIR)/build/extract/extract_science.py -d $(APPS_ROOT_DIR)/dependencies.yaml -w $(SCRATCH_DIR) -e $(APPS_ROOT_DIR)/build/extract/extract.yaml - $Qrsync -acvz $(SCRATCH_DIR)/ukca $(WORKING_DIR)/science/ - $Qrsync -acvz $(SCRATCH_DIR)/casim $(WORKING_DIR)/science/ - + python $(APPS_ROOT_DIR)/build/extract/extract_science.py -d $(APPS_ROOT_DIR)/dependencies.yaml -w $(WORKING_DIR) -e $(APPS_ROOT_DIR)/build/extract/extract.yaml diff --git a/build/extract/extract_science.py b/build/extract/extract_science.py index 042fe6f32..845b87b01 100755 --- a/build/extract/extract_science.py +++ b/build/extract/extract_science.py @@ -1,35 +1,12 @@ import argparse -import subprocess import os -import tempfile import yaml -from shutil import rmtree from pathlib import Path -from typing import Dict, List +from get_git_sources import clone_and_merge, run_command +import logging -def run_command(command): - """ - Run a subprocess command and check output - Inputs: - - command, str with command to run - """ - command = command.split() - result = subprocess.run( - command, - capture_output=True, - text=True, - timeout=120, - shell=False, - check=False, - ) - if result.returncode: - raise RuntimeError( - f"The command '{command}' failed with error:\n\n{result.stderr}" - ) - - -def load_yaml(fpath: Path) -> Dict: +def load_yaml(fpath: Path) -> dict: """ Read in the dependencies.yaml file """ @@ -40,56 +17,45 @@ def load_yaml(fpath: Path) -> Dict: return sources -def clone_dependency(values: Dict, temp_dep: Path) -> None: - """ - Clone the physics dependencies into a temporary directory - """ - - source = values["source"] - ref = values["ref"] - - commands = ( - f"git -C {temp_dep} init", - f"git -C {temp_dep} remote add origin {source}", - f"git -C {temp_dep} fetch origin {ref}", - f"git -C {temp_dep} checkout FETCH_HEAD" - ) - for command in commands: - run_command(command) - - -def extract_files(dependency: str, values: Dict, files: List[str], working: Path): +def extract_files(dependencies: dict, extract_lists: dict, working: Path) -> None: """ Clone the dependency to a temporary location Then copy the desired files to the working directory Then delete the temporary directory """ - tempdir = Path(tempfile.mkdtemp()) - if ( - "PHYSICS_ROOT" not in os.environ - or not Path(os.environ["PHYSICS_ROOT"]).exists() - ): - temp_dep = tempdir / dependency - temp_dep.mkdir(parents=True) - clone_dependency(values, temp_dep) - else: - temp_dep = Path(os.environ["PHYSICS_ROOT"]) / dependency - - working_dep = working / dependency - - # make the working directory location - working_dep.mkdir(parents=True) - - for extract_file in files: - source_file = temp_dep / extract_file - dest_file = working_dep / extract_file - run_command(f"mkdir -p {dest_file.parents[0]}") - copy_command = f"cp -r {source_file} {dest_file}" + mirror_loc = os.getenv("MIRROR_LOC", "") + use_mirrors = bool(mirror_loc) + mirror_loc = Path(mirror_loc) + + for dependency, sources in dependencies.items(): + if dependency not in extract_lists: + continue + files = extract_lists[dependency] + + # If the PHYSICS_ROOT environment variable is provided, then use sources there + if "PHYSICS_ROOT" in os.environ and Path(os.environ["PHYSICS_ROOT"]).exists(): + clone_loc = Path(os.environ["PHYSICS_ROOT"]) / dependency + else: + clone_loc = working.parent / "scratch" / dependency + clone_and_merge(dependency, sources, clone_loc, use_mirrors, mirror_loc) + + # make the working directory location + working_dir = working / dependency + working_dir.mkdir(parents=True, exist_ok=True) + + # rsync extract files from clone loc to the working directory + copy_command = "rsync --include='**/' " + for extract_file in files: + if not extract_file: + continue + if Path(clone_loc / extract_file).is_dir(): + extract_file = extract_file.rstrip("/") + extract_file += "/**" + copy_command += f"--include='{extract_file}' " + copy_command += f"--exclude='*' -avmq {clone_loc}/ {working_dir}" run_command(copy_command) - rmtree(tempdir) - def parse_args() -> argparse.Namespace: """ @@ -101,34 +67,30 @@ def parse_args() -> argparse.Namespace: "-d", "--dependencies", default="./dependencies.yaml", - help="The dependencies file for the apps working copy.", - ) - parser.add_argument( - "-w", "--working", default=".", help="Location to perform extract steps in." + help="The dependencies file for the apps working copy", ) + parser.add_argument("-w", "--working", default=".", help="Build location") parser.add_argument( "-e", "--extract", default="./extract.yaml", help="Path to file containing extract lists", ) - return parser.parse_args() + + args = parser.parse_args() + args.working = Path(args.working) + return args def main(): args: argparse.Namespace = parse_args() - extract_lists: Dict = load_yaml(args.extract) - dependencies: Dict = load_yaml(args.dependencies) - - for dependency in dependencies: - if dependency in extract_lists: - extract_files( - dependency, - dependencies[dependency], - extract_lists[dependency], - Path(args.working), - ) + logging.basicConfig(level=logging.INFO) + + extract_lists: dict = load_yaml(args.extract) + dependencies: dict = load_yaml(args.dependencies) + + extract_files(dependencies, extract_lists, args.working) if __name__ == "__main__": diff --git a/build/extract/get_git_sources.py b/build/extract/get_git_sources.py new file mode 100644 index 000000000..4bf5fd632 --- /dev/null +++ b/build/extract/get_git_sources.py @@ -0,0 +1,402 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +""" +Helper functions for cloning git sources in command line builds +""" + +import re +import subprocess +from datetime import datetime +from typing import Optional, Union +from pathlib import Path +from shutil import rmtree +import shlex +import logging + +logger = logging.getLogger(__name__) + + +def run_command( + command: str, check: bool = True, capture: bool = True, timeout: int = 600 +) -> Optional[subprocess.CompletedProcess]: + """ + Run a subprocess command and return the result object + Inputs: + - command, str with command to run + Outputs: + - result object from subprocess.run + """ + + args = shlex.split(command) + + try: + result = subprocess.run( + args, + capture_output=capture, + text=capture, + timeout=timeout, + shell=False, + check=False, + ) + if check and result.returncode != 0: + err_msg = (result.stderr or "").strip() + logger.error(f"[FAIL] Command failed: {command}\nError: {err_msg}") + raise subprocess.CalledProcessError( + result.returncode, args, output=result.stdout, stderr=result.stderr + ) + return result + + except (subprocess.TimeoutExpired, FileNotFoundError) as e: + logger.error(f"[FAIL] Execution error for '{args[0]}': {e}") + raise + + +def validate_dependencies(dependencies: dict) -> None: + """ + Check that the dependencies file dictionary matches format expectations. + Each dictionary value should be a list of dictionaries (or a single dictionary) + Those dictionaries should have a "source" and a "ref" key + """ + for item, values in dependencies.items(): + failed = False + if isinstance(values, dict): + values = [values] + if not isinstance(values, list): + failed = True + else: + for entry in values: + if not isinstance(entry, dict) or ( + "source" not in entry or "ref" not in entry + ): + failed = True + if failed: + raise ValueError( + f"The dependency {item} does not contain a list of dictionaries (or a " + "single dictionary) with keys of 'source' and 'ref'.\nPlease edit your " + "dependencies.yaml file to satisfy this." + ) + + +def datetime_str() -> str: + """ + Create and return a datetime string at the current time + """ + return datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + +def clone_and_merge( + dependency: str, opts: Union[list, dict], loc: Path, use_mirrors: bool, mirror_loc: Path +) -> None: + """ + Wrapper script for calling get_source and merge_source for a single dependency + + dependency: name of the dependency + opts: dict or list of dicts for a dependency in the dependencies file + loc: path to location to clone to + use_mirrors: bool, use local git mirrors if true + mirror_loc: path to local git mirrors + """ + + if not isinstance(opts, list): + opts = [opts] + + for i, values in enumerate(opts): + if values["ref"] is None: + values["ref"] = "" + + # Clone the first provided source + if i == 0: + get_source( + values["source"], + values["ref"], + loc, + dependency, + use_mirrors, + mirror_loc, + ) + # For all other sources, attempt to merge into the first + else: + merge_source( + values["source"], + values["ref"], + loc, + dependency, + use_mirrors, + mirror_loc, + ) + + +def get_source( + source: str, + ref: str, + dest: Path, + repo: str, + use_mirrors: bool = False, + mirror_loc: Path = Path(""), +) -> None: + """ + Call functions to clone or rsync git source + """ + + if ".git" in source: + if use_mirrors: + logger.info( + f"[{datetime_str()}] Cloning {repo} from {mirror_loc} at ref {ref}" + ) + mirror_loc = Path(mirror_loc) / "MetOffice" / repo + clone_repo_mirror(source, ref, mirror_loc, dest) + else: + logger.info(f"[{datetime_str()}] Cloning {repo} from {source} at ref {ref}") + clone_repo(source, ref, dest) + else: + logger.info(f"[{datetime_str()}] Syncing {repo} at ref {ref}") + sync_repo(source, ref, dest) + + +def merge_source( + source: str, + ref: str, + dest: Path, + repo: str, + use_mirrors: bool = False, + mirror_loc: Path = Path(""), +) -> None: + """ + Merge git source into a local git clone. Assumes dest is a git clone that this + source can be merged into. + """ + + logger.info( + f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Merging " + f"{source} at ref {ref} into {repo}" + ) + + if use_mirrors: + remote_path = Path(mirror_loc) / "MetOffice" / repo + else: + remote_path = source + run_command(f"git -C {dest} remote add local {remote_path}") + + if use_mirrors: + fetch = determine_mirror_fetch(source, ref) + else: + fetch = ref + + run_command(f"git -C {dest} fetch local {fetch}") + command = f"git -C {dest} merge --no-gpg-sign FETCH_HEAD" + result = run_command(command, check=False) + if result.returncode: + unmerged_files = get_unmerged(dest) + if unmerged_files: + handle_merge_conflicts(source, ref, dest, repo) + else: + raise subprocess.CalledProcessError( + result.returncode, command, result.stdout, result.stderr + ) + + # Remove the added remote + run_command(f"git -C {dest} remote remove local") + + +def handle_merge_conflicts(source: str, ref: str, loc: Path, dependency: str) -> None: + """ + If merge conflicts are in `rose-stem/` or `dependencies.yaml` then accept the + current changes and mark as resolved. + If others remain then raise an error + """ + + # For suites, merge conflicts in these files/directories are unimportant so accept + # the current changes + for filepath in ("dependencies.yaml", "rose-stem"): + logger.warning(f"Ignoring merge conflicts in {filepath}") + run_command(f"git -C {loc} checkout --ours -- {filepath}") + run_command(f"git -C {loc} add {filepath}") + + # Check if there are any remaining merge conflicts + unmerged = get_unmerged(loc) + if unmerged: + files = "\n".join(f for f in unmerged) + raise RuntimeError( + "\nA merge conflict has been identified while merging the following branch " + f"into the {dependency} source:\n\nsource: {source}\nref: {ref}\n\n" + f"with conflicting files:{files}" + "\n\nThese will need changing in the source branches to be useable together" + ) + + +def get_unmerged(loc: Path) -> list[str]: + """ + Return list of unmerged files in a git clone + """ + + files = run_command(f"git -C {loc} --no-pager diff --name-only --diff-filter=U") + return files.stdout.split() + + +def clone_repo_mirror( + repo_source: str, + repo_ref: str, + mirror_loc: Path, + loc: Path, +) -> None: + """ + Clone a repo source using a local git mirror. + Assume the mirror is set up as per the Met Office + - repo_source: ssh url of the source repository + - repo_ref: git ref for the source. An empty string will get the default branch + - mirror_loc: path to the local git mirrors + - loc: path to clone the repository to + """ + + # If the repository exists and isn't a git repo, exit now as we don't want to + # overwrite it + if loc.exists(): + if not Path(loc / ".git").exists(): + raise RuntimeError( + f"The destination for the clone of {repo_source} already exists but " + "isn't a git directory. Exiting so as to not overwrite it." + ) + + # Clone if the repo doesn't exist + else: + command = f"git clone {mirror_loc} {loc}" + run_command(command) + + # If not provided a ref, pull the latest repository and return + if not repo_ref: + run_command(f"git -C {loc} pull") + return + + fetch = determine_mirror_fetch(repo_source, repo_ref) + commands = ( + f"git -C {loc} fetch origin {fetch}", + f"git -C {loc} checkout FETCH_HEAD", + ) + for command in commands: + run_command(command) + + +def determine_mirror_fetch(repo_source: str, repo_ref: str) -> str: + """ + Determine the fetch ref for the git mirrors + """ + + repo_source = repo_source.removeprefix("git@github.com:") + user = repo_source.split("/")[0] + # Check that the user is different to the Upstream User + if "MetOffice" in user: + user = None + + # If the ref is a hash then we don't need the fork user as part of the fetch. + # Equally, if the user is the Upstream User, it's not needed + if not user or re.match(r"^\s*([0-9a-f]{40})\s*$", repo_ref): + fetch = repo_ref + else: + fetch = f"{user}/{repo_ref}" + + return fetch + + +def clone_repo(repo_source: str, repo_ref: str, loc: Path) -> None: + """ + Clone the repo and checkout the provided ref + Only if a remote source + - repo_source: ssh url of the source repository + - repo_ref: git ref for the source. An empty string will get the default branch + - loc: path to clone the repository to + """ + + if not loc.exists(): + # Create a clean clone location + loc.mkdir(parents=True) + + # This process is equivalent to doing a git clone + # It saves a small amount of space by not fetching all refs + commands = ( + f"git -C {loc} init", + f"git -C {loc} remote add origin {repo_source}", + f"git -C {loc} fetch origin {repo_ref}", + f"git -C {loc} checkout FETCH_HEAD", + f"git -C {loc} fetch origin main:main", + ) + for command in commands: + run_command(command) + else: + commands = ( + f"git -C {loc} fetch origin {repo_ref}", + f"git -C {loc} checkout FETCH_HEAD", + ) + for command in commands: + run_command(command) + + +def sync_repo(repo_source: str, repo_ref: str, loc: Path) -> None: + """ + Rsync a local git clone and checkout the provided ref + """ + + # Remove if this clone already exists + if loc.exists(): + rmtree(loc) + + # Create a clean clone location + loc.mkdir(parents=True) + + exclude_dirs = [] + try: + host, path = repo_source.split(":", 1) + result = run_command(f"ssh {host} git -C {path} status --ignored -s") + except ValueError: + # In case the path does not contain `host:` - see if it can be accessed locally + result = run_command(f"git -C {repo_source} status --ignored -s") + for ignore_file in result.stdout.split("\n"): + ignore_file = ignore_file.strip() + if not ignore_file.startswith("!!"): + continue + ignore_file = ignore_file.removeprefix("!!").strip() + exclude_dirs.append(ignore_file) + + # Trailing slash required for rsync + command = f"rsync -av {repo_source}/ {loc}" + for item in exclude_dirs: + command = f"{command} --exclude '{item}'" + run_command(command) + + # Fetch the main branch from origin + # Ignore errors - these are likely because the main branch already exists + # Instead write them as warnings + command = f"git -C {loc} fetch origin main:main" + result = run_command(command, check=False) + if result and result.returncode: + logger.warning( + "Fetching main from origin resulted in an error." + "This is likely due to the main branch already existing" + f"\nError message:\n\n{result.stderr}" + ) + + if repo_ref: + command = f"git -C {loc} checkout {repo_ref}" + run_command(command) + + +def set_https(dependencies: dict) -> dict: + """ + Change sources in a dependencies dictionary to use https instead of ssh + """ + + logger.info("Modifying Dependencies to use https") + for dependency, opts in dependencies.items(): + if not isinstance(opts, list): + opts = [opts] + for i, values in enumerate(opts): + if values["source"].startswith("git@github.com:"): + values["source"] = values["source"].replace( + "git@github.com:", "https://github.com/" + ) + opts[i] = values + dependencies[dependency] = opts + + return dependencies diff --git a/build/local_build.py b/build/local_build.py index 2c9d445e4..7f66e614c 100755 --- a/build/local_build.py +++ b/build/local_build.py @@ -17,6 +17,9 @@ import subprocess import argparse import yaml +import logging +from pathlib import Path +from extract.get_git_sources import clone_and_merge def subprocess_run(command): @@ -45,7 +48,7 @@ def get_root_path(): Get the root path of the current working copy """ - return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + return Path(__file__).absolute().parent.parent def determine_core_source(root_dir): @@ -56,7 +59,7 @@ def determine_core_source(root_dir): # Read through the dependencies file and populate revision and source # variables for requested repo - with open(os.path.join(root_dir, "dependencies.yaml"), "r") as stream: + with open(root_dir / "dependencies.yaml", "r") as stream: dependencies = yaml.safe_load(stream) return dependencies["lfric_core"] @@ -70,9 +73,9 @@ def determine_project_path(project, root_dir): # Find the project in either science/ interfaces/ or applications/ for drc in ["science/", "interfaces/", "applications/"]: - path = os.path.join(root_dir, drc) + path = root_dir / drc for item in os.listdir(path): - item_path = os.path.join(path, item) + item_path = path / item if item_path and item == project: return item_path @@ -82,45 +85,6 @@ def determine_project_path(project, root_dir): ) -def clone_dependency(values, temp_dep): - """ - Clone the physics dependencies into a temporary directory - """ - - source = values["source"] - ref = values["ref"] - - commands = ( - f"git -C {temp_dep} init", - f"git -C {temp_dep} remote add origin {source}", - f"git -C {temp_dep} fetch origin {ref}", - f"git -C {temp_dep} checkout FETCH_HEAD" - ) - for command in commands: - subprocess_run(command) - - -def get_lfric_core(core_source, working_dir): - """ - Clone the lfric_core source if the source is a git url - rsync this export into the working dir as the lfric_core source - done so - incremental builds can still be used. - If core_source is a local working copy just rsync from there. - """ - - if core_source["source"].endswith(".git"): - print("Cloning LFRic Core from Github") - lfric_core_loc = f"{working_dir}/scratch/core" - clone_dependency(core_source["source"], core_source["ref"], lfric_core_loc) - print("rsyncing the exported lfric_core source") - else: - lfric_core_loc = core_source["source"] - print("rsyncing the local lfric_core source") - - rsync_command = f"rsync -acvzq {lfric_core_loc}/ {working_dir}/lfric_core" - subprocess_run(rsync_command) - - def build_makefile( root_dir, project_path, @@ -130,7 +94,6 @@ def build_makefile( target, optlevel, psyclone, - um_fcm_platform, verbose, ): """ @@ -140,21 +103,19 @@ def build_makefile( if target == "clean": working_path = working_dir else: - working_path = os.path.join(working_dir, f"{target}_{project}") + working_path = working_dir / f"{target}_{project}" print(f"Calling make command for makefile at {project_path}") make_command = ( f"make {target} -C {project_path} -j {ncores} " f"WORKING_DIR={working_path} " - f"CORE_ROOT_DIR={working_dir}/lfric_core " + f"CORE_ROOT_DIR={working_dir / 'scratch' / 'lfric_core'} " f"APPS_ROOT_DIR={root_dir} " ) if optlevel: make_command += f"PROFILE={optlevel} " if psyclone: make_command += f"PSYCLONE_TRANSFORMATION={psyclone} " - if um_fcm_platform: - make_command += f"UM_FCM_TARGET_PLATFORM={um_fcm_platform} " if verbose: make_command += "VERBOSE=1 " @@ -171,20 +132,31 @@ def main(): ) parser.add_argument( "project", - help="project to build. Will search in both " - "science and projects dirs.", + help="project to build. Will search in both science and projects dirs.", ) parser.add_argument( "-c", "--core_source", default=None, - help="Source for lfric_core. Defaults to looking in " "dependencies file.", + help="Source for lfric_core. Defaults to looking in dependencies file.", + ) + parser.add_argument( + "-m", + "--mirrors", + action="store_true", + help="If true, attempts to use local git mirrors", + ) + parser.add_argument( + "--mirror_loc", + default="/data/users/gitassist/git_mirrors", + help="Location of github mirrors", ) parser.add_argument( "-w", "--working_dir", default=None, - help="Working directory where builds occur. Default to the project " + type=Path, + help="Working directory where builds occur. Defaults to the project " "directory in the working copy.", ) parser.add_argument( @@ -197,7 +169,7 @@ def main(): "-t", "--target", default="build", - help="The makefile target, eg. unit-tests, clean, etc. Default " "of build.", + help="The makefile target, eg. unit-tests, clean, etc. Default of build.", ) parser.add_argument( "-o", @@ -213,14 +185,6 @@ def main(): help="Value passed to PSYCLONE_TRANSFORMATION variable in makefile. " "Defaults to the makefile default", ) - parser.add_argument( - "-u", - "--um_fcm_platform", - default=None, - help="Value passed to UM_FCM_TARGET_PLATFORM variable in makefile, " - "used for build settings for extracted UM physics. Defaults to the " - "makefile default.", - ) parser.add_argument( "-v", "--verbose", @@ -229,6 +193,12 @@ def main(): ) args = parser.parse_args() + logging.basicConfig(level=logging.INFO) + + # If using mirrors, set environment variable for science extract step + if args.mirrors: + os.environ["USE_MIRRORS"] = args.mirror_loc + # Find the root directory of the working copy root_dir = get_root_path() @@ -237,24 +207,26 @@ def main(): # Set the working dir default of the project directory if not args.working_dir: - args.working_dir = os.path.join(project_path, "working") + args.working_dir = Path(project_path) / "working" else: # If the working dir doesn't end in working, set that here - if not args.working_dir.strip("/").endswith("working"): - args.working_dir = os.path.join(args.working_dir, "working") - # Ensure that working_dir is an absolute path - args.working_dir = os.path.abspath(args.working_dir) - # Create the working_dir - subprocess_run(f"mkdir -p {args.working_dir}") + if not args.working_dir.name == "working": + args.working_dir = Path(args.working_dir) / "working" + # Ensure that working_dir is an absolute path and make the directory + args.working_dir = args.working_dir.resolve() + args.working_dir.mkdir(parents=True, exist_ok=True) # Determine the core source if not provided if args.core_source is None: core_source = determine_core_source(root_dir) else: - core_source = {"source": args.core_source} + core_source = {"source": args.core_source, "ref": ""} + + if not isinstance(core_source, list): + core_source = [core_source] - # Export and rsync the lfric_core source - get_lfric_core(core_source, args.working_dir) + core_loc = args.working_dir / "scratch" / "lfric_core" + clone_and_merge("lfric_core", core_source, core_loc, args.mirrors, args.mirror_loc) # Build the makefile build_makefile( @@ -266,7 +238,6 @@ def main(): args.target, args.optlevel, args.psyclone, - args.um_fcm_platform, args.verbose, ) diff --git a/dependencies.yaml b/dependencies.yaml index caab36487..8455aefc4 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -19,11 +19,11 @@ casim: source: git@github.com:MetOffice/casim.git - ref: 2025.12.1 + ref: 2026.03.1 jules: source: git@github.com:MetOffice/jules.git - ref: 2025.12.1 + ref: 2026.03.1 lfric_apps: source: @@ -31,24 +31,24 @@ lfric_apps: lfric_core: source: git@github.com:MetOffice/lfric_core.git - ref: 2025.12.1 + ref: 2026.03.1 moci: source: git@github.com:MetOffice/moci.git - ref: 2025.12.1 + ref: 2026.03.1 SimSys_Scripts: source: git@github.com:MetOffice/SimSys_Scripts.git - ref: 2025.12.1 + ref: 2026.03.1 socrates: source: git@github.com:MetOffice/socrates.git - ref: 2025.12.1 + ref: 2026.03.1 socrates-spectral: source: git@github.com:MetOffice/socrates-spectral.git - ref: 2025.12.1 + ref: 2026.03.1 ukca: source: git@github.com:MetOffice/ukca.git - ref: 2025.12.1 + ref: 2026.03.1 diff --git a/documentation/source/conf.py b/documentation/source/conf.py index 7954ab6d0..9d6ae59a1 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -19,7 +19,8 @@ # ones. extensions = [ 'sphinx_sitemap', - 'sphinx_design' + 'sphinx_design', + 'sphinx.ext.intersphinx' ] # Add any paths that contain templates here, relative to this directory. @@ -117,3 +118,12 @@ def superscript_substitution_role(name, rawtext, text, lineno, inliner, def setup(app): app.add_role('superscript_substitution', superscript_substitution_role) + +# Options for intersphinx mapping extension +# To discover the available objects in the target project (e.g. psyclone), run: +# python -m sphinx.ext.intersphinx https://psyclone.readthedocs.io/en/stable/objects.inv +intersphinx_mapping = { + 'psyclone': ('https://psyclone.readthedocs.io/en/stable/', None), + 'simsys': ('https://metoffice.github.io/simulation-systems/', None), + 'lfric_core': ('https://metoffice.github.io/lfric_core/', None) +} diff --git a/documentation/source/developer_guide/local_builds.rst b/documentation/source/developer_guide/local_builds.rst index 9e5bd9310..c57f67e62 100644 --- a/documentation/source/developer_guide/local_builds.rst +++ b/documentation/source/developer_guide/local_builds.rst @@ -67,3 +67,19 @@ This table lists the command line arguments available: | | | will request verbose output | | | | from the makefile. | +----------------------+-----------------------------+-----------------------------+ +| ``-m --mirrors`` | False | If True, this will attempt | +| ``store_true`` | | to extract using local | +| | | github mirrors | ++----------------------+-----------------------------+-----------------------------+ +| ``--mirror-loc`` | MetOffice Mirror Location | The path to the github | +| | | mirror location | ++----------------------+-----------------------------+-----------------------------+ + +Incremental Builds +------------------ + +The local build script will attempt to build incrementally if a previous attempt +at the build exists. This should happen automatically if the working directory +is the same. If there are large changes then it may be sensible to start the +build afresh by cleaning the build ``-t clean`` (or deleting the working +directory). diff --git a/documentation/source/faq.rst b/documentation/source/faq.rst new file mode 100644 index 000000000..7bb5eebc2 --- /dev/null +++ b/documentation/source/faq.rst @@ -0,0 +1,16 @@ +.. ----------------------------------------------------------------------------- + (c) Crown copyright Met Office. All rights reserved. + The file LICENCE, distributed with this code, contains details of the terms + under which the code may be used. + ----------------------------------------------------------------------------- + +:html_theme.sidebar_secondary.remove: true + +:orphan: + +.. _faqs: + +See also: :ref:`LFRic Core FAQs`. + +Frequently Asked Questions +========================== diff --git a/documentation/source/getting_started/guide.rst b/documentation/source/getting_started/guide.rst index e63e6e94c..e36533c55 100644 --- a/documentation/source/getting_started/guide.rst +++ b/documentation/source/getting_started/guide.rst @@ -13,6 +13,8 @@ information on the dependencies required to run any of the LFRic based applications including those found in LFRic Core. The :ref:`User Guide ` describes the purpose of the applications and how to use them. +The :ref:`Science Guide ` describes the various +science schemes implemented and used in the modelling applications. The :ref:`Developer Guide ` contains guidance for those doing development of the applications themselves. diff --git a/documentation/source/getting_started/repository_contents.rst b/documentation/source/getting_started/repository_contents.rst index 99de12678..e6ca47bdb 100644 --- a/documentation/source/getting_started/repository_contents.rst +++ b/documentation/source/getting_started/repository_contents.rst @@ -3,6 +3,8 @@ The file LICENCE, distributed with this code, contains details of the terms under which the code may be used. ----------------------------------------------------------------------------- +.. Some of the content of this file has been produced with the assistance of + GitHub Copilot. .. _repository_contents: @@ -11,20 +13,25 @@ Contents of the Repository The repository contains the following directories: -- The ``science`` directory contains several libraries of science code and - interface code which allows calls to external models each of which can be used - in the development of applications. For example, the **gungho** - library provides the dynamical core used in the |Momentum| Atmosphere - application. - The ``applications`` directory contains the different applications that have been developed using the LFRic Core and the science libraries. Applications include the main |Momentum| Atmosphere application as well as smaller applications that test subsections of different models (e.g. transport, solver, etc.). -- The ``rose-stem`` directory contains the system test suites for development - testing. - The ``build`` directory contains additional build scripts required by the modelling system. +- The ``documentation`` directory contains the source code for this + documentation. +- The ``interfaces`` directory contains interface code to couple to sub models + such as the JULES land surface model. +- The ``rose-meta`` dorectory contains links to the rose metadata for the + different libraries and applications. +- The ``rose-stem`` directory contains the system test suites for development + testing. +- The ``science`` directory contains several libraries of science code which can + be used in the development of applications. For example, the **gungho** + library provides the dynamical core used in the |Momentum| Atmosphere + application. Many of the directories contain directories of unit and integration tests, directories of Rose metadata, and Makefiles for building diff --git a/documentation/source/index.rst b/documentation/source/index.rst index 1f4584cff..52ee78d6f 100644 --- a/documentation/source/index.rst +++ b/documentation/source/index.rst @@ -20,7 +20,8 @@ modelling. This code base contains most of the core infrastructure used by the applications found in the LFRic Apps repository and is documented `here `__. -.. grid:: 3 +.. grid:: 2 2 4 4 + :gutter: 2 .. grid-item-card:: :text-align: center @@ -50,6 +51,20 @@ the applications found in the LFRic Apps repository and is documented User Guide + .. grid-item-card:: + :text-align: center + + Guide to the science included in the models + + +++ + .. button-ref:: science_guide_index + :ref-type: ref + :color: primary + :outline: + :expand: + + Science Guide + .. grid-item-card:: :text-align: center @@ -74,10 +89,71 @@ Key initial aims for the |Momentum| atmosphere model are as follows: - The infrastructure will be flexible enough to support future evolutions of the science. +.. grid:: 2 2 4 4 + :gutter: 3 3 4 4 + + .. grid-item-card:: + :text-align: center + + :material-round:`menu_book;2em` + + +++ + .. button-ref:: glossary_of_terms + :ref-type: ref + :color: primary + :outline: + :expand: + + Glossary + + .. grid-item-card:: + :text-align: center + + :material-round:`help_center;2em` + + +++ + .. button-ref:: faqs + :ref-type: ref + :color: primary + :outline: + :expand: + + FAQs + + .. grid-item-card:: + :text-align: center + + :fab:`github;fa-xl` + + +++ + .. button-link:: https://github.com/MetOffice/lfric_apps + :ref-type: ref + :color: primary + :outline: + :expand: + + GitHub + + .. grid-item-card:: + :text-align: center + + :far:`comments;fa-xl` + + +++ + .. button-link:: https://github.com/MetOffice/simulation-systems/discussions + :ref-type: ref + :color: primary + :outline: + :expand: + + Discussions + + .. toctree:: :maxdepth: 1 :hidden: getting_started/index user_guide/index + science_guide/index developer_guide/index diff --git a/documentation/source/science_guide/README.md b/documentation/source/science_guide/README.md new file mode 100644 index 000000000..6aa984e3e --- /dev/null +++ b/documentation/source/science_guide/README.md @@ -0,0 +1,25 @@ +# Updating the Science Guide +This README file describes how to update the Science Guide documentation for +LFRic Apps. + +## Adding new sections +To add a new section to the Science Guide, follow these steps: +1. Create a new directory under `documentation/source/science_guide/` with a + descriptive name for the section. +2. Inside this new directory, create an `index.rst` file. This file will + automatically be added to the table of contents. +3. Include a reference at the top of the `index.rst` file below the copyright + notice of the form ```.. _
_index:``` to allow cross-referencing. +4. If subsections are needed, create additional `.rst` files in the same + directory. Including the following table of contents tree in the sections + `index.rst` will pick up additional files and include them in the contents. +``` restructuredtext +.. toctree:: + :maxdepth: 1 + :glob: + + * +``` +5. Follow the documentation style guide described in + [Sphinx Documentation Formatting](https://metoffice.github.io/lfric_core/how_to_contribute/style_guides/documentation_style_guide.html#text-formatting) + diff --git a/documentation/source/science_guide/example_section/index.rst b/documentation/source/science_guide/example_section/index.rst new file mode 100644 index 000000000..4c98e8821 --- /dev/null +++ b/documentation/source/science_guide/example_section/index.rst @@ -0,0 +1,19 @@ +.. ----------------------------------------------------------------------------- + (c) Crown copyright Met Office. All rights reserved. + The file LICENCE, distributed with this code, contains details of the terms + under which the code may be used. + ----------------------------------------------------------------------------- + +.. _example_section_index: + +Example Section +=============== + +Contained here are descriptions of the example section schemes available in the +model. + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/documentation/source/science_guide/example_section/scheme1.rst b/documentation/source/science_guide/example_section/scheme1.rst new file mode 100644 index 000000000..5c1aa50f4 --- /dev/null +++ b/documentation/source/science_guide/example_section/scheme1.rst @@ -0,0 +1,21 @@ +.. ----------------------------------------------------------------------------- + (c) Crown copyright Met Office. All rights reserved. + The file LICENCE, distributed with this code, contains details of the terms + under which the code may be used. + ----------------------------------------------------------------------------- + +.. _scheme1: + +Scheme 1 +======== + +Info about Scheme1. + + +Subsection 1 +------------ +Details about subsection 1. + +Subsection 2 +------------ +Details about subsection 2. \ No newline at end of file diff --git a/documentation/source/science_guide/example_section/scheme2.rst b/documentation/source/science_guide/example_section/scheme2.rst new file mode 100644 index 000000000..5af43e5dc --- /dev/null +++ b/documentation/source/science_guide/example_section/scheme2.rst @@ -0,0 +1,21 @@ +.. ----------------------------------------------------------------------------- + (c) Crown copyright Met Office. All rights reserved. + The file LICENCE, distributed with this code, contains details of the terms + under which the code may be used. + ----------------------------------------------------------------------------- + +.. _scheme2: + +Scheme 2 +======== + +Info about Scheme 2. + + +Subsection 1 +------------ +Details about subsection 1. + +Subsection 2 +------------ +Details about subsection 2. \ No newline at end of file diff --git a/documentation/source/science_guide/index.rst b/documentation/source/science_guide/index.rst new file mode 100644 index 000000000..dc765ca95 --- /dev/null +++ b/documentation/source/science_guide/index.rst @@ -0,0 +1,20 @@ +.. ----------------------------------------------------------------------------- + (c) Crown copyright Met Office. All rights reserved. + The file LICENCE, distributed with this code, contains details of the terms + under which the code may be used. + ----------------------------------------------------------------------------- +.. _science_guide_index: + +Science Guide +============= + +Contained here are descriptions of the various science schemes available in +the model. + +.. toctree:: + :maxdepth: 2 + :hidden: + :glob: + + */index + diff --git a/documentation/source/user_guide/checkpointing/lfric_atm_checkpoint.rst b/documentation/source/user_guide/checkpointing/lfric_atm_checkpoint.rst index 17be30420..2a664b051 100644 --- a/documentation/source/user_guide/checkpointing/lfric_atm_checkpoint.rst +++ b/documentation/source/user_guide/checkpointing/lfric_atm_checkpoint.rst @@ -9,18 +9,26 @@ LFRic atmosphere checkpoint/restart system ========================================== -The LFRic atmosphere ``lfric_atm`` application can be configured to generate a -checkpoint dump at the end of each model run. The checkpoint dump can be read in -by a new integration of the model allowing further timesteps to be run. The dump +The LFRic atmosphere ``lfric_atm`` application can be configured to generate +checkpoint dumps at multiple points within a model run. A checkpoint dump can be read in +by a new integration of the model allowing further timesteps to be run. Each dump is written using XIOS. Requesting checkpoint restart ----------------------------- Set ``checkpoint_write=.true.`` in the ``io`` namelist of the model -configuration to generate a checkpoint dump at the end of a model run. The -checkpoint dump will be named after the ``checkpoint_stem_name`` string in the -``files`` namelist appended with the number of the last timestep of the run. +configuration to turn on checkpoint writing. The times when checkpoint files +will be written are defined by the ``checkpoint_times`` list. The +``checkpoint_times`` must be real values in seconds corresponding to an integer +number of timesteps in the model run (e.g. if ``dt=0.5`` the +``checkpoint_times`` can include ``0.5`` and ``1.0`` etc. but **not** ``0.3``). +Setting ``end_of_run_checkpoint=.true.`` will write a checkpoint file at the end +of the run. Only one checkpoint file will be written at the end of a run even if +both the final timestep is included in the ``checkpoint_times`` list and the +``end_of_run_checkpoint`` flag is set to ``.true.``. The checkpoint dumps will +be named after the ``checkpoint_stem_name`` string in the ``files`` namelist +appended with timestep number of the checkpoint time. Set ``checkpoint_read=.true.`` in the ``io`` namelist to restart a run from an existing checkpoint dump. The expected start timestep will be defined by diff --git a/interfaces/coupled_interface/rose-meta/coupling/version30_31.py b/interfaces/coupled_interface/rose-meta/coupling/version30_31.py new file mode 100644 index 000000000..1eae88f05 --- /dev/null +++ b/interfaces/coupled_interface/rose-meta/coupling/version30_31.py @@ -0,0 +1,207 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/coupling + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/coupled_interface/rose-meta/coupling/versions.py b/interfaces/coupled_interface/rose-meta/coupling/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/coupled_interface/rose-meta/coupling/versions.py +++ b/interfaces/coupled_interface/rose-meta/coupling/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/coupled_interface/rose-meta/coupling/vn3.1/rose-meta.conf b/interfaces/coupled_interface/rose-meta/coupling/vn3.1/rose-meta.conf new file mode 100644 index 000000000..47acbb91f --- /dev/null +++ b/interfaces/coupled_interface/rose-meta/coupling/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-gungho/vn3.1 diff --git a/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90 b/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90 index 8a5a0425d..6149953e4 100644 --- a/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90 +++ b/interfaces/coupled_interface/source/algorithm/coupler_update_prognostics_mod.X90 @@ -72,6 +72,8 @@ module coupler_update_prognostics_mod type( field_type ), pointer :: lat type( field_type ) :: snow_mass + real(r_def) :: rhosnow_r_def + call depository%get_field('ocn_cpl_point', ocn_cpl_point_ptr) select case(fld%get_name()) @@ -138,7 +140,10 @@ module coupler_update_prognostics_mod call depository%get_field('tile_snow_mass', fld_ptr1) ! Calculate snow mass from snow depth ! snow_mass = rhosnow * snow_depth(fld) - call invoke( a_times_X(snow_mass, rhosnow, fld ) ) + ! rhosnow is defined in double precision in JULES + ! Make a copy for case of single precision compilation + rhosnow_r_def = rhosnow + call invoke( a_times_X(snow_mass, rhosnow_r_def, fld ) ) ! Insert into the sea ice section of tile_snow_mass call invoke( masked_multi_insert_kernel_type(fld_ptr1, snow_mass, & ocn_cpl_point_ptr, & diff --git a/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/version30_31.py b/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/version30_31.py new file mode 100644 index 000000000..92966a5f6 --- /dev/null +++ b/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/version30_31.py @@ -0,0 +1,282 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/jedi_lfric_interface + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/versions.py b/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/versions.py +++ b/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/vn3.1/rose-meta.conf b/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/vn3.1/rose-meta.conf new file mode 100644 index 000000000..a95b2cf2e --- /dev/null +++ b/interfaces/jedi_lfric_interface/rose-meta/jedi_lfric_interface/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-linear/vn3.1 diff --git a/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 b/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 index c7d2bb148..5a665c30d 100644 --- a/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 +++ b/interfaces/jedi_lfric_interface/source/driver/linear/jedi_lfric_linear_modeldb_driver_mod.f90 @@ -191,7 +191,7 @@ subroutine initialise_modeldb( modeldb_name, filename, mpi_obj, modeldb, atl_si_ aerosol_twod_mesh ) ! Instantiate the linearisation state - call linear_create_ls_analytic( modeldb, mesh ) + call linear_create_ls_analytic( modeldb, mesh, twod_mesh ) ! 4. Initialise the model diff --git a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 index c630b998d..d1715d984 100644 --- a/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 +++ b/interfaces/jedi_lfric_interface/source/field/atlas_field_interface_mod.F90 @@ -46,7 +46,7 @@ module atlas_field_interface_mod use field_mod, only : field_type, field_proxy_type use field_parent_mod, only : field_parent_type use fs_continuity_mod, only : W3, Wtheta, name_from_functionspace - use constants_mod, only : i_def, str_def, l_def + use constants_mod, only : i_def, str_def, l_def, r_def implicit none @@ -394,7 +394,7 @@ subroutine copy_to_lfric( self, return_code ) atlas_ij = self%map_horizontal(ij) lfric_ij = (ij-1)*n_vertical_lfric field_proxy%data(lfric_ij+lfric_kstart:lfric_ij+n_vertical_lfric) & - = self%atlas_data(atlas_kstart:atlas_kend:atlas_kdirection,atlas_ij) + = real(self%atlas_data(atlas_kstart:atlas_kend:atlas_kdirection,atlas_ij), r_def) end do ! Fill missing data if required @@ -410,7 +410,7 @@ subroutine copy_to_lfric( self, return_code ) atlas_ij = self%map_horizontal(ij) lfric_ij = (ij-1)*n_vertical_lfric field_proxy%data(lfric_ij+1) & - = self%atlas_data(atlas_kstart,atlas_ij) + = real(self%atlas_data(atlas_kstart,atlas_ij), r_def) end do end if @@ -466,7 +466,7 @@ subroutine copy_from_lfric_ad(self) lfric_ij = (ij-1)*n_vertical_lfric field_proxy%data(lfric_ij+lfric_kstart:lfric_ij+n_vertical_lfric) & = field_proxy%data(lfric_ij+lfric_kstart:lfric_ij+n_vertical_lfric) & - + self%atlas_data(atlas_kstart:atlas_kend:atlas_kdirection,atlas_ij) + + real(self%atlas_data(atlas_kstart:atlas_kend:atlas_kdirection,atlas_ij), r_def) end do ! Initialise out of scope variable to zero diff --git a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 index b1ab23597..9f7185cd5 100644 --- a/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 +++ b/interfaces/jedi_lfric_interface/source/field/jedi_lfric_linear_fields_mod.f90 @@ -21,7 +21,7 @@ !> ii) all three "moist_dyn" fields. !> module jedi_lfric_linear_fields_mod - use constants_mod, only : i_def, str_def, r_def + use constants_mod, only : i_def, str_def, r_def, l_def use field_mod, only : field_type use field_collection_mod, only : field_collection_type use fs_continuity_mod, only : W3, Wtheta, W2 @@ -35,6 +35,7 @@ module jedi_lfric_linear_fields_mod integer( kind=i_def ), parameter :: element_order_h = 0 integer( kind=i_def ), parameter :: element_order_v = 0 integer( kind=i_def ), parameter :: nvars = 10 + integer( kind=i_def ), parameter :: ls_nvars = 11 character( len=str_def ), parameter, public :: & variable_names(nvars) = (/'theta ', & 'exner ', & @@ -46,6 +47,18 @@ module jedi_lfric_linear_fields_mod 'm_cl ', & 'm_r ', & 'm_s '/) + character( len=str_def ), parameter, public :: & + ls_variable_names(ls_nvars) = (/'theta ', & + 'exner ', & + 'rho ', & + 'u_in_w3 ', & + 'v_in_w3 ', & + 'w_in_wth ', & + 'm_v ', & + 'm_cl ', & + 'm_r ', & + 'm_s ', & + 'land_fraction'/) integer( kind=i_def ), parameter, public :: & variable_function_spaces(nvars) = (/Wtheta, & @@ -58,6 +71,31 @@ module jedi_lfric_linear_fields_mod Wtheta, & Wtheta, & Wtheta/) + integer( kind=i_def ), parameter, public :: & + ls_variable_function_spaces(ls_nvars) = (/Wtheta, & + W3, & + W3, & + W3, & + W3, & + Wtheta, & + Wtheta, & + Wtheta, & + Wtheta, & + Wtheta, & + W3/) + + logical( kind=l_def ), parameter, public :: & + ls_variable_is_2d(ls_nvars) = (/.false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .false., & + .true./) public :: create_linear_fields @@ -69,33 +107,42 @@ module jedi_lfric_linear_fields_mod !> @brief Create a field collection that includes the linear model variables !> !> @param [in] mesh Pointer to a mesh object +!> @param [in] twod_mesh Pointer to a 2D mesh object !> @param [out] linear_fields A field collection that includes the linear !> fields -subroutine create_linear_fields( mesh, linear_fields ) +subroutine create_linear_fields( mesh, twod_mesh, linear_fields ) implicit none type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh type( field_collection_type ), intent(out) :: linear_fields ! Local type( field_type ) :: field + type( mesh_type ), pointer :: mesh_for_field character( len=str_def ) :: variable_name integer :: i ! Setup the field_collection - call linear_fields%initialise(name = 'linear_state_trajectory', table_len = nvars) + call linear_fields%initialise(name = 'linear_state_trajectory', table_len = ls_nvars) ! Create and add the fields defined in the list of variable names - do i = 1, nvars + do i = 1, ls_nvars + + variable_name = trim(ls_variable_names(i)) - variable_name = trim(variable_names(i)) + if (ls_variable_is_2d(i)) then + mesh_for_field => twod_mesh + else + mesh_for_field => mesh + end if call field%initialise( & - vector_space = function_space_collection%get_fs(mesh, & + vector_space = function_space_collection%get_fs(mesh_for_field, & element_order_h, & element_order_v, & - variable_function_spaces(i)), & + ls_variable_function_spaces(i)), & name = variable_name ) call linear_fields%add_field( field ) diff --git a/interfaces/jedi_lfric_interface/source/io/jedi_lfric_io_setup_mod.F90 b/interfaces/jedi_lfric_interface/source/io/jedi_lfric_io_setup_mod.F90 index f245ff4b8..ec58daee2 100644 --- a/interfaces/jedi_lfric_interface/source/io/jedi_lfric_io_setup_mod.F90 +++ b/interfaces/jedi_lfric_interface/source/io/jedi_lfric_io_setup_mod.F90 @@ -166,8 +166,6 @@ subroutine init_io( context_name, & file_list => io_context%get_filelist() call jedi_lfric_init_files(file_list, file_meta) - call io_context%set_timer_flag(subroutine_timers) - ! Setup the context call io_context%initialise( context_name ) call lfric_comm%set_comm_mpi_val(communicator) diff --git a/interfaces/jedi_lfric_interface/source/mesh/jedi_lfric_mesh_setup_mod.F90 b/interfaces/jedi_lfric_interface/source/mesh/jedi_lfric_mesh_setup_mod.F90 index 24665d5b9..a1058e3d4 100644 --- a/interfaces/jedi_lfric_interface/source/mesh/jedi_lfric_mesh_setup_mod.F90 +++ b/interfaces/jedi_lfric_interface/source/mesh/jedi_lfric_mesh_setup_mod.F90 @@ -10,6 +10,7 @@ module jedi_lfric_mesh_setup_mod use add_mesh_map_mod, only: assign_mesh_maps use base_mesh_config_mod, only: GEOMETRY_SPHERICAL, & GEOMETRY_PLANAR + use check_configuration_mod, only: get_required_stencil_depth use constants_mod, only: str_def, i_def, l_def, r_def use create_mesh_mod, only: create_mesh use driver_mesh_mod, only: init_mesh @@ -62,7 +63,7 @@ subroutine initialise_mesh( mesh_name, configuration, mpi_obj, alt_mesh_name ) integer(i_def), parameter :: one_layer = 1_i_def integer(i_def) :: geometry integer(i_def) :: extrusion_method - integer(i_def) :: stencil_depth + integer(i_def), allocatable :: stencil_depths(:) integer(i_def) :: number_of_layers integer(i_def) :: i real(r_def) :: domain_bottom @@ -122,14 +123,19 @@ subroutine initialise_mesh( mesh_name, configuration, mpi_obj, alt_mesh_name ) !------------------------------------------------------------------------- ! 1.2 Create the required meshes !------------------------------------------------------------------------- - stencil_depth = 2 + + allocate(stencil_depths(size(base_mesh_names))) + call get_required_stencil_depth( & + stencil_depths, base_mesh_names, configuration & + ) + apply_partition_check = .false. call init_mesh( configuration, & mpi_obj%get_comm_rank(), & mpi_obj%get_comm_size(), & base_mesh_names, & extrusion, & - stencil_depth, & + stencil_depths, & apply_partition_check ) allocate( twod_names, source=base_mesh_names ) @@ -140,6 +146,11 @@ subroutine initialise_mesh( mesh_name, configuration, mpi_obj, alt_mesh_name ) alt_name=twod_names ) call assign_mesh_maps(twod_names) + deallocate(twod_names) + deallocate(stencil_depths) + deallocate(extrusion) + if (allocated(extrusion_2d)) deallocate(extrusion_2d) + end subroutine initialise_mesh end module jedi_lfric_mesh_setup_mod diff --git a/interfaces/jules_interface/build/import.mk b/interfaces/jules_interface/build/import.mk index bb1c8870b..73b35d289 100644 --- a/interfaces/jules_interface/build/import.mk +++ b/interfaces/jules_interface/build/import.mk @@ -8,8 +8,7 @@ export PROJECT_SOURCE = $(APPS_ROOT_DIR)/interfaces/jules_interface/source .PHONY: import-jules_interface import-jules_interface: # Get a copy of the source code from the JULES repository - python $(APPS_ROOT_DIR)/build/extract/extract_science.py -d $(APPS_ROOT_DIR)/dependencies.yaml -w $(SCRATCH_DIR) -e $(APPS_ROOT_DIR)/interfaces/jules_interface/build/extract.yaml - $Qrsync -acvz $(SCRATCH_DIR)/jules $(WORKING_DIR)/ + python $(APPS_ROOT_DIR)/build/extract/extract_science.py -d $(APPS_ROOT_DIR)/dependencies.yaml -w $(WORKING_DIR) -e $(APPS_ROOT_DIR)/interfaces/jules_interface/build/extract.yaml # Extract the interface code $Q$(MAKE) $(QUIET_ARG) -f $(LFRIC_BUILD)/extract.mk \ diff --git a/interfaces/jules_interface/rose-meta/jules-lfric/HEAD/rose-meta.conf b/interfaces/jules_interface/rose-meta/jules-lfric/HEAD/rose-meta.conf index 2cddaa708..cd725e1b6 100644 --- a/interfaces/jules_interface/rose-meta/jules-lfric/HEAD/rose-meta.conf +++ b/interfaces/jules_interface/rose-meta/jules-lfric/HEAD/rose-meta.conf @@ -1,3 +1,15 @@ +############################################################################### +# This is the LFRic flavour of the JULES metadata +############################################################################### +# This should only contain: +# * Import statements from lfric-jules-shared. +# * LFRic specific amendments to the imported metadata. +# The majority of the metadata should be under rose-meta/lfric-jules-shared. +# +# This file in the future will reside in the JULES repository and will import +# jules-shared directly from there when the build system has been developed to +# allow this. +# # Please see jules:wiki:SharingJULESmetadata import=lfric-jules-shared/jules-hydrology/HEAD @@ -15,6 +27,31 @@ import=lfric-jules-shared/jules-hydrology/HEAD [namelist:jules_hydrology=l_hydrology] trigger=namelist:jules_hydrology=l_var_rainfrac: .true.; +[namelist:jules_model_environment_lfric] +compulsory=true +description=Not all JULES options are available in all environments in which JULES is run e.g. standalone, + =UM, LFRic (LIS, MONC, CABLE). The model environment is specified here so that options that are + =unavailable can be made inaccessible via the metadata and thus will not appear in the gui. +ns=namelist/JULES Science Settings/jules_model_environment +sort-key=01 +title=Model environment interface +url=http://jules-lsm.github.io/latest/namelists/model_environment.nml.html#namelist-JULES_MODEL_ENVIRONMENT + +[namelist:jules_model_environment_lfric=l_jules_parent] +compulsory=true +description=Switch to identify the environment in which JULES is being run. + =No science code is associated with this switch, only what science options are available. + =THIS HAS TO BE LFRIC SPECIFIC FOR NOW AS A RESULT OF THE WAY THAT + =LFRIC COUPLED PROCESSES NAMELIST FILES. +!enumeration=true +fail-if=this != "'lfric'"; # This should indicate that LFRic is the parent model. +trigger=namelist:jules_surface=l_elev_land_ice: 'not_lfric'; + =namelist:jules_surface=l_elev_lw_down: 'not_lfric'; + =namelist:jules_surface=l_flake_model: 'not_lfric'; + =namelist:jules_surface=l_point_data: 'not_lfric'; +value-titles=LFRic +values='lfric' + [namelist:jules_radiation=fixed_sea_albedo] description=If using i_sea_alb_method='fixed', the global value of albedo to use. @@ -50,24 +87,52 @@ values='marshall','taillandier' [namelist:jules_snow=i_relayer_opt] values='original','inverse' +[namelist:jules_surface=all_tiles] +values='off','on' + [namelist:jules_surface=anthrop_heat_option] fail-if=this != "'dukes'"; # The DUKES fixed annual cycle is the only currently available option in LFRic trigger=namelist:jules_surface=anthrop_heat_mean: 'flanner'; values='dukes','flanner' [namelist:jules_surface=cor_mo_iter] +trigger=namelist:jules_surface=beta_cnv_bl: 'improved'; value-titles=Limit Obukhov length in low winds, =Improve initial guess (preferred) values='lim_oblen','improved' +[namelist:jules_surface=fd_hill_option] +value-titles=capped low hill +values='capped_lowhill' + [namelist:jules_surface=fd_stability_dep] value-titles=Off,Surface Ri values='none','surf_ri' [namelist:jules_surface=formdrag] -trigger=namelist:jules_surface=fd_stability_dep: 'eff_z0','dist_drag'; +fail-if= +trigger=namelist:jules_surface=orog_drag_param: 'eff_z0','dist_drag'; + =namelist:jules_surface=fd_stability_dep: 'eff_z0','dist_drag'; + =namelist:jules_surface=fd_hill_option: 'dist_drag'; values='none','eff_z0','dist_drag' +[namelist:jules_surface=i_modiscopt] +fail-if= +value-titles=On +values='on' + +[namelist:jules_surface=iscrntdiag] +fail-if= +value-titles=Decoupled with transitional effects +values='decoupled_trans' + +[namelist:jules_surface=l_elev_land_ice] +fail-if= +trigger= + +[namelist:jules_surface=l_flake_model] +trigger= + [namelist:jules_surface=l_urban2t] trigger=namelist:jules_surface_types=urban_canyon: .true.; =namelist:jules_surface_types=urban_roof: .true.; @@ -75,12 +140,15 @@ trigger=namelist:jules_surface_types=urban_canyon: .true.; =namelist:jules_urban: .true.; =namelist:jules_urban=anthrop_heat_scale: .true.; =namelist:files=urban_ancil_path: .true.; - =namelist:stochastic_physics=rp_lsfc_z0_urban_mult: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0_urban_mult: .true.; [namelist:jules_surface=l_vary_z0m_soil] +fail-if= trigger=namelist:files=soil_rough_ancil_path: .true. ; [namelist:jules_surface=srf_ex_cnv_gust] +fail-if= +trigger= type=logical [namelist:jules_vegetation=can_rad_mod] diff --git a/interfaces/jules_interface/rose-meta/jules-lfric/version30_31.py b/interfaces/jules_interface/rose-meta/jules-lfric/version30_31.py new file mode 100644 index 000000000..94bd4b868 --- /dev/null +++ b/interfaces/jules_interface/rose-meta/jules-lfric/version30_31.py @@ -0,0 +1,122 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/jules_interface/rose-meta/jules-lfric/versions.py b/interfaces/jules_interface/rose-meta/jules-lfric/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/jules_interface/rose-meta/jules-lfric/versions.py +++ b/interfaces/jules_interface/rose-meta/jules-lfric/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/jules_interface/rose-meta/jules-lfric/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/jules-lfric/vn3.1/rose-meta.conf new file mode 100644 index 000000000..07ecf662c --- /dev/null +++ b/interfaces/jules_interface/rose-meta/jules-lfric/vn3.1/rose-meta.conf @@ -0,0 +1,181 @@ +############################################################################### +# This is the LFRic flavour of the JULES metadata +############################################################################### +# This should only contain: +# * Import statements from lfric-jules-shared. +# * LFRic specific amendments to the imported metadata. +# The majority of the metadata should be under rose-meta/lfric-jules-shared. +# +# This file in the future will reside in the JULES repository and will import +# jules-shared directly from there when the build system has been developed to +# allow this. +# +# Please see jules:wiki:SharingJULESmetadata + +import=lfric-jules-shared/jules-hydrology/vn3.1 + =lfric-jules-shared/jules-nvegparm/vn3.1 + =lfric-jules-shared/jules-pftparm/vn3.1 + =lfric-jules-shared/jules-radiation/vn3.1 + =lfric-jules-shared/jules-sea-seaice/vn3.1 + =lfric-jules-shared/jules-snow/vn3.1 + =lfric-jules-shared/jules-soil/vn3.1 + =lfric-jules-shared/jules-surface/vn3.1 + =lfric-jules-shared/jules-surface-types/vn3.1 + =lfric-jules-shared/jules-urban/vn3.1 + =lfric-jules-shared/jules-vegetation/vn3.1 + +[namelist:jules_hydrology=l_hydrology] +trigger=namelist:jules_hydrology=l_var_rainfrac: .true.; + +[namelist:jules_model_environment_lfric] +compulsory=true +description=Not all JULES options are available in all environments in which JULES is run e.g. standalone, + =UM, LFRic (LIS, MONC, CABLE). The model environment is specified here so that options that are + =unavailable can be made inaccessible via the metadata and thus will not appear in the gui. +ns=namelist/JULES Science Settings/jules_model_environment +sort-key=01 +title=Model environment interface +url=http://jules-lsm.github.io/latest/namelists/model_environment.nml.html#namelist-JULES_MODEL_ENVIRONMENT + +[namelist:jules_model_environment_lfric=l_jules_parent] +compulsory=true +description=Switch to identify the environment in which JULES is being run. + =No science code is associated with this switch, only what science options are available. + =THIS HAS TO BE LFRIC SPECIFIC FOR NOW AS A RESULT OF THE WAY THAT + =LFRIC COUPLED PROCESSES NAMELIST FILES. +!enumeration=true +fail-if=this != "'lfric'"; # This should indicate that LFRic is the parent model. +trigger=namelist:jules_surface=l_elev_land_ice: 'not_lfric'; + =namelist:jules_surface=l_elev_lw_down: 'not_lfric'; + =namelist:jules_surface=l_flake_model: 'not_lfric'; + =namelist:jules_surface=l_point_data: 'not_lfric'; +value-titles=LFRic +values='lfric' + +[namelist:jules_radiation=fixed_sea_albedo] +description=If using i_sea_alb_method='fixed', the global value of albedo to use. + +[namelist:jules_radiation=i_sea_alb_method] +trigger=namelist:jules_radiation=l_sea_alb_var_chl: 'jin'; + =namelist:jules_radiation=fixed_sea_albedo: 'fixed'; +value-titles=Barker and Li 1995,Jin et al. 2011,Fixed global value +values='barker','jin','fixed' + +[namelist:jules_radiation=l_albedo_obs] +trigger=namelist:files=albedo_vis_ancil_path: .true. ; + =namelist:files=albedo_nir_ancil_path: .true. ; + =namelist:jules_nvegparm=albsnf_nvgu_io: .true.; + =namelist:jules_nvegparm=albsnf_nvgl_io: .true.; + +[namelist:jules_radiation=l_sea_alb_var_chl] +trigger=namelist:files=sea_ancil_path: .true. ; + +[namelist:jules_snow=can_clump] +fail-if=len(this) != namelist:jules_surface_types=npft; # A value must be given for each PFT + =all(this == 0) and any(namelist:jules_snow=cansnowpft == '.true.'); # Results in floating point exception if 0. Only used if can_model = 4 (JULES default), cansnowpft = TRUE on that tile and l_embedded_snow = TRUE (LFRic default). + +[namelist:jules_snow=cansnowpft] +compulsory=true +length=5 + +[namelist:jules_snow=i_basal_melting_opt] +values='none','instant' + +[namelist:jules_snow=i_grain_growth_opt] +values='marshall','taillandier' + +[namelist:jules_snow=i_relayer_opt] +values='original','inverse' + +[namelist:jules_surface=all_tiles] +values='off','on' + +[namelist:jules_surface=anthrop_heat_option] +fail-if=this != "'dukes'"; # The DUKES fixed annual cycle is the only currently available option in LFRic +trigger=namelist:jules_surface=anthrop_heat_mean: 'flanner'; +values='dukes','flanner' + +[namelist:jules_surface=cor_mo_iter] +trigger=namelist:jules_surface=beta_cnv_bl: 'improved'; +value-titles=Limit Obukhov length in low winds, + =Improve initial guess (preferred) +values='lim_oblen','improved' + +[namelist:jules_surface=fd_hill_option] +value-titles=capped low hill +values='capped_lowhill' + +[namelist:jules_surface=fd_stability_dep] +value-titles=Off,Surface Ri +values='none','surf_ri' + +[namelist:jules_surface=formdrag] +fail-if= +trigger=namelist:jules_surface=orog_drag_param: 'eff_z0','dist_drag'; + =namelist:jules_surface=fd_stability_dep: 'eff_z0','dist_drag'; + =namelist:jules_surface=fd_hill_option: 'dist_drag'; +values='none','eff_z0','dist_drag' + +[namelist:jules_surface=i_modiscopt] +fail-if= +value-titles=On +values='on' + +[namelist:jules_surface=iscrntdiag] +fail-if= +value-titles=Decoupled with transitional effects +values='decoupled_trans' + +[namelist:jules_surface=l_elev_land_ice] +fail-if= +trigger= + +[namelist:jules_surface=l_flake_model] +trigger= + +[namelist:jules_surface=l_urban2t] +trigger=namelist:jules_surface_types=urban_canyon: .true.; + =namelist:jules_surface_types=urban_roof: .true.; + =namelist:jules_surface_types=urban: .false.; + =namelist:jules_urban: .true.; + =namelist:jules_urban=anthrop_heat_scale: .true.; + =namelist:files=urban_ancil_path: .true.; + =namelist:stochastic_physics=rp_lsfc_z0_urban_mult: .true.; + +[namelist:jules_surface=l_vary_z0m_soil] +fail-if= +trigger=namelist:files=soil_rough_ancil_path: .true. ; + +[namelist:jules_surface=srf_ex_cnv_gust] +fail-if= +trigger= +type=logical + +[namelist:jules_vegetation=can_rad_mod] +values='one','four','five','six' + +[namelist:jules_vegetation=l_spec_veg_z0] +trigger=namelist:jules_pftparm=z0v_io: .true.; + =namelist:stochastic_physics=rp_lsfc_z0v: .true.; + =namelist:stochastic_physics=rp_lsfc_z0v_max: .true.; + =namelist:stochastic_physics=rp_lsfc_z0v_min: .true.; + +# Dummy page to force sort order for JULES Science Settings +[namespace:science] +ns=namelist/JULES Science Settings +sort-key=Section-A12b + +# Dummy page to force sort order for Snow other parameters +[namespace:snow_other] +ns=namelist/JULES Science Settings/jules_snow/Other parameters +sort-key=02 + +# Dummy page to force sort order for Snow radiation parameters +[namespace:snow_radiation] +ns=namelist/JULES Science Settings/jules_snow/Radiation parameters +sort-key=01 + +# Dummy page to force sort order for JULES Surface Types +[namespace:surface_types] +ns=namelist/JULES Surface Types +sort-key=Section-A12a diff --git a/interfaces/jules_interface/rose-meta/jules-lsm/version30_31.py b/interfaces/jules_interface/rose-meta/jules-lsm/version30_31.py new file mode 100644 index 000000000..d44665eee --- /dev/null +++ b/interfaces/jules_interface/rose-meta/jules-lsm/version30_31.py @@ -0,0 +1,124 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/jules_interface/rose-meta/jules-lsm/versions.py b/interfaces/jules_interface/rose-meta/jules-lsm/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/jules_interface/rose-meta/jules-lsm/versions.py +++ b/interfaces/jules_interface/rose-meta/jules-lsm/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/jules_interface/rose-meta/jules-lsm/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/jules-lsm/vn3.1/rose-meta.conf new file mode 100644 index 000000000..1a4e38225 --- /dev/null +++ b/interfaces/jules_interface/rose-meta/jules-lsm/vn3.1/rose-meta.conf @@ -0,0 +1,489 @@ +############################################################################### +# JULES metadata structure: +# - lfric-jules-shared = JULES metadata shared between parent models. +# = This a copy of jules-shared from the JULES repository. +# = lfric-jules-shared and jules-shared must be identical. +# - jules-lfric = LFRic specific amendments to jules-shared. +# = Imports lfric-jules-shared. +# - jules-lsm = LFRic-JULES interface metadata not relevant to JULES +# repository. +# = Imports jules-lfric. +# +# jules-lfric & jules-shared will be imported from JULES repository in future. +# +# Please see https://code.metoffice.gov.uk/trac/jules/wiki/SharingJULESmetadata +############################################################################### + +import=jules-lfric/vn3.1 + +[namelist:ideal_surface] +compulsory=true +description=Idealised surface settings +ns=namelist/Job/Initial conditions/Surface +sort-key=Section-A05 +title=Surface + +[namelist:ideal_surface=canopy_height] +compulsory=true +description=Canopy height of each plant type +fail-if=len(this) != namelist:jules_surface_types=npft +help=Canopy height of each plant type +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-03 +type=real + +[namelist:ideal_surface=leaf_area_index] +compulsory=true +description=Leaf area index of each plant type +fail-if=len(this) != namelist:jules_surface_types=npft +help=Leaf area index of each plant type +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-04 +type=real + +[namelist:ideal_surface=n_snow_layers] +compulsory=true +description=Snow layers on each tile +fail-if=len(this) != namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg + namelist:jules_sea_seaice=nice + 1 +help=The initial number of snow layers on each surface tile + = + =The order of tiles is land, sea, sea-ice +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-08 +type=integer + +[namelist:ideal_surface=snow_depth] +compulsory=true +description=Snow depth on each tile +fail-if=len(this) != namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg + namelist:jules_sea_seaice=nice + 1 +help=The initial snow depth on each surface tile + = + =The order of tiles is land, sea, sea-ice +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-09 +type=real + +[namelist:ideal_surface=snow_layer_ice_mass] +compulsory=true +description=Ice mass of each snow layer on tiles +fail-if=len(this) != 3*(namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg) +help=The initial ice mass of each snow layer + = + =The order in tiles 1-n for layer 1, then tiles 1-n for layer 2 etc +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-11 +type=real + +[namelist:ideal_surface=snow_layer_temp] +compulsory=true +description=Temperature of each snow layer on tiles +fail-if=len(this) != 3*(namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg) +help=The initial temperature of each snow layer + = + =The order in tiles 1-n for layer 1, then tiles 1-n for layer 2 etc +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-12 +type=real + +[namelist:ideal_surface=snow_layer_thickness] +compulsory=true +description=Thickness of each snow layer on tiles +fail-if=len(this) != 3*(namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg) +help=The initial thickness of each snow layer + = + =The order in tiles 1-n for layer 1, then tiles 1-n for layer 2 etc +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-10 +type=real + +[namelist:ideal_surface=soil_moisture] +compulsory=true +description=Soil moisture content +help=Soil moisture content on soil levels +!kind=default +length=4 +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-05 +type=real + +[namelist:ideal_surface=soil_temperature] +compulsory=true +description=Soil temperature +help=Temperature of soil levels +!kind=default +length=4 +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-06 +type=real + +[namelist:ideal_surface=surf_tile_fracs] +compulsory=true +description=Fraction of each surface tile +fail-if=len(this) != namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg + namelist:jules_sea_seaice=nice + 1 +help=The fraction within a grid-box of each surface tile + = + =The order of tiles is land, sea, sea-ice + = + =The fractions should sum to 1 +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-01 +type=real + +[namelist:ideal_surface=surf_tile_temps] +compulsory=true +description=Fraction of each surface tile +fail-if=len(this) != namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg + namelist:jules_sea_seaice=nice + 1 +help=The initial temperature of each surface tile + = + =The order of tiles is land, sea, sea-ice +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-02 +type=real + +[namelist:ideal_surface=tile_snow_mass] +compulsory=true +description=Snow mass on each tile +fail-if=len(this) != namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg + namelist:jules_sea_seaice=nice + 1 +help=The initial snow mass on each surface tile + = + =The order of tiles is land, sea, sea-ice +!kind=default +length=: +ns=namelist/Job/Initial conditions/Surface +sort-key=Panel-07 +type=real + +[namelist:specified_surface] +compulsory=true +description=Further Idealised surface settings +ns=namelist/Science/Specified Surface +sort-key=Section-A05 +title=Specified Surface + +[namelist:specified_surface=function_amplitude_e] +compulsory=true +description=Amplitude of the function used for surface latent heat flux +help=Specifies the amplitude of the analytical function used for calculating the + =surface latent heat flux +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=function_amplitude_h] +compulsory=true +description=Amplitude of the function used for surface sensible heat flux +help=Specifies the amplitude of the analytical function used for calculating the + =surface sensible heat flux +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=function_name_fluxes] +compulsory=true +description=Name of the function used for surface latent and sensible heat fluxes +!enumeration=true +help=Specifies function name used for calculating surface latent and sensible heat fluxes + =If constant, uses the single values set in specified_flux_h and specified_flux_e. profile_size should be set to 1. + =If time-interpolated, uses the time-varying arrays set in specified_flux_h and specified_flux_e, where the arrays are of length profile_size. + =If sinusoidal, fluxes are set to + =amplitude * sin( 2 * pi * current_time / period + phase ) + =If diurnal, fluxes are set to + =max(0, amplitude * cos( pi* (time_of_max_flux - current_time) / length_of_day )^1.3 ) +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +trigger=namelist:specified_surface=function_amplitude_e: 'sinusoidal', 'diurnal'; + =namelist:specified_surface=function_period_e: 'sinusoidal'; + =namelist:specified_surface=function_phase_e: 'sinusoidal'; + =namelist:specified_surface=function_amplitude_h: 'sinusoidal', 'diurnal'; + =namelist:specified_surface=function_period_h: 'sinusoidal'; + =namelist:specified_surface=function_phase_h: 'sinusoidal'; + =namelist:specified_surface=length_of_day: 'diurnal'; + =namelist:specified_surface=time_of_max_flux: 'diurnal'; + =namelist:specified_surface=length_of_day: 'diurnal'; + =namelist:specified_surface=time_data: 'time_interpolated'; + =namelist:specified_surface=profile_size: 'constant','time_interpolated'; + =namelist:specified_surface=specified_flux_e: 'constant','time_interpolated'; + =namelist:specified_surface=specified_flux_h: 'constant','time_interpolated'; + =namelist:specified_surface=time_units: 'sinusoidal', 'diurnal', 'time_interpolated'; +value-titles=Constant, Time Interpolated, Sinusoidal function, Diurnal function +values='constant', 'time_interpolated', 'sinusoidal', 'diurnal' + +[namelist:specified_surface=function_name_sst] +compulsory=true +description=Name of the function used for sea surface temperatures +!enumeration=true +help=Specifies the function name used for calculating surface sensible heat flux + = If constant, uses the sea surface tile value set by surf_tile_temps option found in + = ideal_surface namelist. + = If time_interpolated, uses the time-varying array set in sea_surf_temps found in the + = specified_surface namelist. +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +trigger=namelist:specified_surface=time_data_sst: 'time_interpolated'; + =namelist:specified_surface=profile_size_sst: 'time_interpolated'; + =namelist:specified_surface=time_units_sst: 'time_interpolated'; + =namelist:specified_surface=sea_surf_temps: 'time_interpolated'; +value-titles=Constant, Time Interpolated +values='constant', 'time_interpolated' + +[namelist:specified_surface=function_period_e] +compulsory=true +description=Period of the function used for surface latent heat flux +help=Specifies the period of the sinusoidal analytical function used for calculating + =latent heat flux +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=function_period_h] +compulsory=true +description=Period of the function used for surface sensible heat flux +help=Specifies the period of the sinusoidal analytical function used for calculating + =sensible heat flux +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=function_phase_e] +compulsory=true +description=Phase of the function used for latent heat flux +help=Specifies the phase of the sinusoidal analytical function used for calculating the + =latent heat flux +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=function_phase_h] +compulsory=true +description=Phase of the function used for sensible heat flux +help=Specifies the phase of the sinusoidal analytical function used for calculating the + =sensible heat flux +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=internal_flux_method] +compulsory=true +description=How to prescribe the internal flux +!enumeration=true +help=Either a constant value or a 2D map +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +trigger=namelist:files=internal_flux_ancil_path: 'non_uniform' ; + =namelist:specified_surface=internal_flux_value: 'uniform' ; +value-titles=Uniform, Non-Uniform +values='uniform','non_uniform' + +[namelist:specified_surface=internal_flux_value] +compulsory=true +description=Constant internal flux value +help=Use the Stefan-Boltzmann law to calculate the flux from + =internal temperature T_int +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=length_of_day] +compulsory=true +description=Duration of daylight +help=Specifies the duration of daylight, in units that are consistent with + =the length_of_day option, used for the diurnal analytical function. +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=profile_size] +compulsory=true +description=Number of points in varying flux profile +help=Number of data points in the specified_flux_h and specified_flux_e + =arrays +!kind=default +ns=namelist/Science/Specified Surface +range=0: +sort-key=Panel-A03e +type=integer + +[namelist:specified_surface=profile_size_sst] +compulsory=true +description=Number of points in sst profile +help=Number of data points in the sea_surf_temps arrays +!kind=default +ns=namelist/Science/Specified Surface +range=0: +sort-key=Panel-A03e +type=integer + +[namelist:specified_surface=sea_surf_temps] +!bounds=namelist:specified_surface=profile_size_sst +compulsory=true +description=Time-varying sea surface temperature profile +help=Sea surface temperature values (K) used at times specified, overides + =the sea surface tile value set by surf_tile_temps option found in + =ideal_surface namelist. +!kind=default +length=: +ns=namelist/Science/Specified Surface +sort-key=Panel-A03d +type=real + +[namelist:specified_surface=specified_flux_e] +!bounds=namelist:specified_surface=profile_size +compulsory=true +description=Surface latent heat flux [Wm-2] +help=Fixed or time-varying value used throughout the run. +!kind=default +length=: +ns=namelist/Science/Specified Surface +sort-key=Panel-A01a +type=real + +[namelist:specified_surface=specified_flux_h] +!bounds=namelist:specified_surface=profile_size +compulsory=true +description=Surface sensible heat flux [Wm-2] +help=Fixed or time-varying value used throughout the run +!kind=default +length=: +ns=namelist/Science/Specified Surface +sort-key=Panel-A01b +type=real + +[namelist:specified_surface=surf_temp_forcing] +compulsory=true +description=Forcing of the surface temperature +!enumeration=true +help=E.g. increment due to an internal flux +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +trigger=namelist:specified_surface=internal_flux_method: 'int_flux' ; +value-titles=None, Internal flux +values='none','int_flux' + +[namelist:specified_surface=time_data] +!bounds=namelist:specified_surface=profile_size +compulsory=true +description=Time values +help=Time values corresponding with the time-varying fluxes +!kind=default +length=: +ns=namelist/Science/Specified Surface +range=0.0: +sort-key=Panel-A03c +type=real + +[namelist:specified_surface=time_data_sst] +!bounds=namelist:specified_surface=profile_size_sst +compulsory=true +description=Time values +help=Time values corresponding with the time-varying ssts +!kind=default +length=: +ns=namelist/Science/Specified Surface +range=0.0: +sort-key=Panel-A03c +type=real + +[namelist:specified_surface=time_of_max_flux] +compulsory=true +description=Time of maximum flux +help=Specifies the time of day when the flux reaches its maximum value. + =The units must be consistent with the units used by the length_of_day option. + =Used for the diurnal analytical function. +!kind=default +ns=namelist/Science/Specified Surface +sort-key=Panel-A03 +type=real + +[namelist:specified_surface=time_units] +compulsory=true +description=Units of the time_data list/ function_period +!enumeration=true +help=Specifies the units of the time data/ wave period used. +ns=namelist/Science/Specified Surface +value-titles=Seconds,Minutes,Hours,Days +values='seconds','minutes','hours','days' + +[namelist:specified_surface=time_units_sst] +compulsory=true +description=Units of the time_data list/ function_period +!enumeration=true +help=Specifies the units of the time data/ wave period used. +ns=namelist/Science/Specified Surface +value-titles=Seconds,Minutes,Hours,Days +values='seconds','minutes','hours','days' + +[namelist:surface] +compulsory=true +description=Surface parametrisations used in the surface interface +ns=namelist/Science/Surface Interface +sort-key=Section-A12 + +[namelist:surface=check_soilm_negatives] +description=Switch to check if soil moisture has become negative as part of the + =lake water conservation scheme +ns=namelist/Science/Surface Interface/Soil +sort-key=Panel-B01a +type=logical + +[namelist:surface=emis_method_sea] +compulsory=true +description=Emissivity method for open sea + = Two options for spectrally varying emissivity in addition to a fixed emissivity: + = D. Feldman et al. (2014) https://doi.org/10.1073/pnas.1413640111 and + = R. Saunders et al. (2018) https://doi.org/10.5194/gmd-11-2717-2018 for IREMIS. +!enumeration=true +ns=namelist/Science/Surface Interface/Radiation +value-titles=1: Fixed, + =2: Feldman, + =3: IREMIS +values='fixed','feldman','iremis' + +[namelist:surface=emis_method_soil] +compulsory=true +description=Emissivity method for soil + = Option for spectrally varying emissivity in addition to a fixed emissivity: + = D. Feldman et al. (2014) https://doi.org/10.1073/pnas.1413640111 +!enumeration=true +ns=namelist/Science/Surface Interface/Radiation +value-titles=1: Fixed, + =2: Feldman Desert +values='fixed','feldman_desert' + +[namelist:surface=lake_water_conservation] +compulsory=true +description=Use the lake water conservation scheme +help=The inland water tile (aka lake tile) is a freely evaporating surface that does not deplete the local water supply. In order to conserve water the lake water conservation scheme decreases the level 4 soil moisture globally to account for this. +ns=namelist/Science/Surface Interface/Soil +sort-key=Panel-B01 +trigger=namelist:surface=check_soilm_negatives: .true.; +type=logical diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-hydrology/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-hydrology/vn3.1/rose-meta.conf new file mode 100644 index 000000000..782d74687 --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-hydrology/vn3.1/rose-meta.conf @@ -0,0 +1,27 @@ +[namelist:jules_hydrology] +compulsory=true +ns=namelist/JULES Science Settings/jules_hydrology +sort-key=Section-A12g +title=Hydrology options +url=http://jules-lsm.github.io/latest/namelists/jules_hydrology.nml.html#namelist-JULES_HYDROLOGY + +[namelist:jules_hydrology=l_hydrology] +compulsory=true +description=Enable soil hydrology +!kind=default +sort-key=Panel-G01 +trigger=namelist:jules_hydrology=l_var_rainfrac: .true.; + =namelist:jules_hydrology=l_top: .true.; + =namelist:jules_hydrology=l_pdm: .true.; + =namelist:jules_hydrology=l_limit_gsoil: .true.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_hydrology.nml.html#JULES_HYDROLOGY::l_hydrology + +[namelist:jules_hydrology=l_var_rainfrac] +compulsory=true +description=Enable variable large scale and convective rain fractions + =SHOULD NOT BE USED IN STANDALONE - Please see online docs. +!kind=default +sort-key=Panel-G02 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_hydrology.nml.html#JULES_HYDROLOGY::l_var_rainfrac diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-nvegparm/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-nvegparm/vn3.1/rose-meta.conf new file mode 100644 index 000000000..1cb77755f --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-nvegparm/vn3.1/rose-meta.conf @@ -0,0 +1,121 @@ +[namelist:jules_nvegparm] +compulsory=true +description=Parameters required for each of the non-vegetated surface types. +ns=namelist/JULES Science Settings/jules_nvegparm +sort-key=Section-A12n +title=Non-vegetated surface parameters +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#namelist-JULES_NVEGPARM +widget[rose-config-edit]=cylc8_compat.PageArrayTable + +[namelist:jules_nvegparm=albsnc_nvg_io] +compulsory=true +description=Snow-covered albedo +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +range=0:1 +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::albsnc_nvg_io + +[namelist:jules_nvegparm=albsnf_nvg_io] +compulsory=true +description=Snow-free albedo +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +range=-1:1 +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::albsnf_nvg_io + +[namelist:jules_nvegparm=albsnf_nvgl_io] +compulsory=true +description=Lower limit on albsnf_nvg_io +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +range=0:1 +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::albsnf_nvgl_io + +[namelist:jules_nvegparm=albsnf_nvgu_io] +compulsory=true +description=Upper limit on albsnf_nvg_io +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +range=0:1 +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::albsnf_nvgu_io + +[namelist:jules_nvegparm=catch_nvg_io] +compulsory=true +description=Capacity for water (kg m-2) +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::catch_nvg_io + +[namelist:jules_nvegparm=ch_nvg_io] +compulsory=true +description=Heat capacity of this surface type (J K-1 m-2) +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::ch_nvg_io + +[namelist:jules_nvegparm=emis_nvg_io] +compulsory=true +description=Surface emissivity +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +range=0:1 +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::emis_nvg_io + +[namelist:jules_nvegparm=gs_nvg_io] +compulsory=true +description=Surface conductance (m s-1) +fail-if=len(this) != namelist:jules_surface_types=nnvg +length=: +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::gs_nvg_io + +[namelist:jules_nvegparm=infil_nvg_io] +compulsory=true +description=Infiltration enhancement factor +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::infil_nvg_io + +[namelist:jules_nvegparm=vf_nvg_io] +compulsory=true +description=Fractional coverage of non-vegetation "canopy" +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +range=0:1 +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::vf_nvg_io + +[namelist:jules_nvegparm=z0_nvg_io] +compulsory=true +description=Roughness length for momentum (m) +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::z0_nvg_io + +[namelist:jules_nvegparm=z0hm_nvg_io] +compulsory=true +description=Ratio of the roughness length for heat to the roughness length for momentum +fail-if=len(this) != namelist:jules_surface_types=nnvg +!kind=default +length=: +type=real +url=http://jules-lsm.github.io/latest/namelists/nveg_params.nml.html#JULES_NVEGPARM::z0hm_nvg_io diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-pftparm/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-pftparm/vn3.1/rose-meta.conf new file mode 100644 index 000000000..c9486d05e --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-pftparm/vn3.1/rose-meta.conf @@ -0,0 +1,167 @@ +[namelist:jules_pftparm] +compulsory=true +description=This section is organised into two panels: + = "Radiation parameters" contains parameters related to radiative transfer in vegetation, + = "Other parameters" contains everything else. +ns=namelist/JULES Science Settings/jules_pftparm +sort-key=Section-A12l +title=PFT parameters +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#namelist-JULES_PFTPARM +widget[rose-config-edit]=cylc8_compat.PageArrayTable + +[namelist:jules_pftparm=albsnc_max_io] +compulsory=true +description=Snow-covered albedo for large LAI +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Radiation parameters +range=0:1 +sort-key=Panel-HR03 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::albsnc_max_io + +[namelist:jules_pftparm=alnir_io] +compulsory=true +description=NIR Leaf reflection coeff. + =Leaf reflection coefficient for Near Infra Red wavelengths > 690nm. +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Radiation parameters +range=0:1 +sort-key=Panel-HR03 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::alnir_io + +[namelist:jules_pftparm=alpar_io] +compulsory=true +description=VIS Leaf reflection coeff. + =Leaf reflection coefficient for wavelengths < 690nm (Photosyntehtically Active Radiation). +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Radiation parameters +range=0:1 +sort-key=Panel-HR03 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::alpar_io + +[namelist:jules_pftparm=catch0_io] +compulsory=true +description=Minimum canopy capacity (kg m-2) +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Other parameters +sort-key=Panel-HO05 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::catch0_io + +[namelist:jules_pftparm=dcatch_dlai_io] +compulsory=true +description=Rate of change of canopy capacity with LAI (kg m-2) +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Other parameters +sort-key=Panel-HO05 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::dcatch_dlai_io + +[namelist:jules_pftparm=fsmc_p0_io] +compulsory=true +description=PFT-dependent parameter governing the threshold at which the plant starts to experience water stress + =due to lack of water in the soil +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Other parameters +sort-key=Panel-HO05 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::fsmc_p0_io + +[namelist:jules_pftparm=kext_io] +compulsory=true +description=Light extinction coefficient + =Used with Beers Law for light absorption through tile canopies +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Radiation parameters +sort-key=Panel-HR02 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::kext_io + +[namelist:jules_pftparm=knl_io] +compulsory=true +description=Decay of nitrogen through the canopy for canopy radiation model 6 + =SHOULD NOT BE THE SAME AS KN! +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Other parameters +sort-key=Panel-HO05 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::knl_io + +[namelist:jules_pftparm=omega_io] +compulsory=true +description=VIS Leaf scattering coeff. + =Leaf scattering coefficient for wavelengths < 690nm (Photosyntehtically Active Radiation). +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Radiation parameters +range=0:1 +sort-key=Panel-HR03 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::omega_io + +[namelist:jules_pftparm=omnir_io] +compulsory=true +description=NIR Leaf scattering coeff. + =Leaf scattering coefficient for Near Infra Red wavelengths > 690nm. +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Radiation parameters +range=0:1 +sort-key=Panel-HR03 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::omnir_io + +[namelist:jules_pftparm=z0hm_pft_io] +compulsory=true +description=Ratio of the roughness length for heat to the roughness length for momentum +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Other parameters +sort-key=Panel-HO05 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::z0hm_pft_io + +[namelist:jules_pftparm=z0v_io] +compulsory=true +description=Specified vegetation roughness length for momentum (if l_spec_veg_z0) +fail-if=len(this) != namelist:jules_surface_types=npft +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_pftparm/Other parameters +sort-key=Panel-HO05 +type=real +url=http://jules-lsm.github.io/latest/namelists/pft_params.nml.html#JULES_PFTPARM::z0v_io + +# Dummy page to force sort order for pftparm other parameters +[namespace:pftparm_other] +description=Parameters not related to radiative transfer of vegetation. + =Related parameters are grouped together where appropriate. +ns=namelist/JULES Science Settings/jules_pftparm/Other parameters +sort-key=02 + +# Dummy page to force sort order for pftparm radiation parameters +[namespace:pftparm_radiation] +description=Parameters related to radiative transfer of vegetation +ns=namelist/JULES Science Settings/jules_pftparm/Radiation parameters +sort-key=01 diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-radiation/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-radiation/vn3.1/rose-meta.conf new file mode 100644 index 000000000..2e9f46c19 --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-radiation/vn3.1/rose-meta.conf @@ -0,0 +1,113 @@ +[namelist:jules_radiation] +compulsory=true +ns=namelist/JULES Science Settings/jules_radiation +sort-key=Section-A12d +title=Radiation options +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#namelist-JULES_RADIATION + +[namelist:jules_radiation=fixed_sea_albedo] +compulsory=true +description=If using i_sea_alb_method=4 or 5, the global value of albedo to use. +!kind=default +range=0.0:1.0 +sort-key=Panel-B05a +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::fixed_sea_albedo + +[namelist:jules_radiation=i_sea_alb_method] +compulsory=true +description=Choice of model for the Ocean Surface Albedo (open water, + =ice free) +!enumeration=true +sort-key=Panel-B05 +trigger=namelist:jules_radiation=l_sea_alb_var_chl: 3; + =namelist:jules_radiation=fixed_sea_albedo: 4,5; + =namelist:jules_radiation=l_spec_sea_alb: 1,2,3; +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::i_sea_alb_method +value-titles=Briegleb and Ramanathan 1982,Barker and Li 1995,Jin et al. 2011,Fixed global value,Fixed sea with sea-ice param +values=1,2,3,4,5 + +[namelist:jules_radiation=l_albedo_obs] +compulsory=true +description=Scale albedos of land-surface tiles to agree with obs +!kind=default +sort-key=Panel-B01 +trigger=namelist:jules_pftparm=albsnf_maxu_io: .true.; + =namelist:jules_pftparm=albsnf_maxl_io: .true.; + =namelist:jules_pftparm=alparu_io: .true.; + =namelist:jules_pftparm=alparl_io: .true.; + =namelist:jules_pftparm=alniru_io: .true.; + =namelist:jules_pftparm=alnirl_io: .true.; + =namelist:jules_pftparm=omegau_io: .true.; + =namelist:jules_pftparm=omegal_io: .true.; + =namelist:jules_pftparm=omniru_io: .true.; + =namelist:jules_pftparm=omnirl_io: .true.; + =namelist:jules_nvegparm=albsnf_nvgu_io: .true.; + =namelist:jules_nvegparm=albsnf_nvgl_io: .true.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::l_albedo_obs + +[namelist:jules_radiation=l_hapke_soil] +compulsory=true +description=Switch to enable Hapke's model of soil reflectance to include a zenith-angle dependence, but without the opposition effect. +!kind=default +sort-key=Panel-B03 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::l_hapke_soil + +[namelist:jules_radiation=l_niso_direct] +compulsory=true +description=Use the full non-isotropic expression for direct scattering in plant canopies. +!kind=default +sort-key=Panel-B02a1 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::l_niso_direct + +[namelist:jules_radiation=l_partition_albsoil] +compulsory=true +description=Switch to apply a spectral partitioning of the broad-band soil albedo. +!kind=default +sort-key=Panel-B04 +trigger=namelist:jules_radiation=ratio_albsoil: .true.; + =namelist:jules_radiation=swdn_frac_albsoil: .true.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::l_partition_albsoil + +[namelist:jules_radiation=l_sea_alb_var_chl] +compulsory=true +description=Use spatially varying chlorophyll content to calculate the open sea albedos + =NOT AVAILABLE TO STANDALONE +help=The Jin et al. parameterisation of open sea albedo includes chlorophyll content. This can either be: + =FALSE: Held constant at 0.5 mg m-3, + =or, + =TRUE: Input as an ancillary field. +!kind=default +sort-key=Panel-B05b +type=logical + +[namelist:jules_radiation=l_spec_alb_bs] +compulsory=true +description=Use a single value for both the direct and diffuse beams +!kind=default +sort-key=Panel-B02a +trigger=namelist:jules_radiation=l_niso_direct: .false.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::l_spec_alb_bs + +[namelist:jules_radiation=ratio_albsoil] +compulsory=true +description=Ratio of the NIR to the VIS albedo of bare soil +!kind=default +range=1.0:10.0 +sort-key=Panel-B04a +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::ratio_albsoil + +[namelist:jules_radiation=swdn_frac_albsoil] +compulsory=true +description=The fraction of the total downward SW radiation assumed to be in the NIR part of the spectrum when partitioning the broad-band soil albedo. +!kind=default +range=0.0:1.0 +sort-key=Panel-B04b +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_radiation.nml.html#JULES_RADIATION::swdn_frac_albsoil diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-sea-seaice/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-sea-seaice/vn3.1/rose-meta.conf new file mode 100644 index 000000000..8f6938c9e --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-sea-seaice/vn3.1/rose-meta.conf @@ -0,0 +1,245 @@ +[namelist:jules_sea_seaice] +compulsory=true +ns=namelist/JULES Science Settings/jules_sea_seaice +sort-key=Section-A12i +title=Sea and sea-ice options + +[namelist:jules_sea_seaice=alpham] +compulsory=true +description=Original HadGEM sea ice albedo scheme: Albedo of sea-ice at + =melting point (TM, if .not.l_ssice_albedo), + =or albedo of snow on sea-ice at melting point (TM, if + =l_ssice_albedo) ("M" for "melting") +!kind=default +range=0:1 +sort-key=Panel-C01 +type=real + +[namelist:jules_sea_seaice=amip_ice_thick] +compulsory=true +description=Calculate ice thickness from ice fraction +!kind=default +sort-key=Panel-C01 +type=logical + +[namelist:jules_sea_seaice=beta_evap] +compulsory=true +description=Efficiency of evaporation from sea-surface +help=This parameter controls the efficiency with which water can evaporate from a sea-surface. + = The default value is 1.0, moisture availability is effectively unrestricted. + = However, lower values can be useful for idealised modelling, + = restricting the evaporation rate. + = For example, a value of 0.0 would result in no evaporation. +!kind=default +range=0.0:1.0 +sort-key=Panel-C05 +type=real + +[namelist:jules_sea_seaice=buddy_sea] +compulsory=true +description=Use neighbouring sea point wind-speeds in coastal grid points +!enumeration=true +!kind=default +sort-key=Panel-C01a +value-titles=Off,On +values='Off','On' + +[namelist:jules_sea_seaice=cdn_hw_sea] +compulsory=true +description=Neutral drag coefficient over the sea at high wind speeds. +!kind=default +sort-key=Panel-C06a +type=real + +[namelist:jules_sea_seaice=cdn_max_sea] +compulsory=true +description=Maximum value of the neutral drag coefficient over open sea. +!kind=default +sort-key=Panel-C06b +type=real + +[namelist:jules_sea_seaice=dtice] +compulsory=true +description=Original HadGEM sea ice albedo scheme: Temperature range in which + =albedo of sea-ice (if .not.l_ssice_albedo), + =or of snow on sea-ice (if l_ssice_albedo), + =varies between its limits (recommended range 5-10K) +!kind=default +range=0.1:50 +sort-key=Panel-C02 +type=real + +[namelist:jules_sea_seaice=emis_sea] +compulsory=true +description=Emissivity of open sea +!kind=default +sort-key=Panel-C03 +type=real + +[namelist:jules_sea_seaice=emis_sice] +compulsory=true +description=Emissivity of sea-ice +!kind=default +sort-key=Panel-C04 +type=real + +[namelist:jules_sea_seaice=hcap_sea] +description=Heat capacity of the slab ocean (J K-1 m-2) +!kind=default +range=0.0: +sort-key=Panel-C14a +type=real + +[namelist:jules_sea_seaice=i_high_wind_drag] +compulsory=true +description=Option to impose a special treatment of drag at high wind speeds. +!enumeration=true +sort-key=Panel-C06 +trigger=namelist:jules_sea_seaice=cdn_hw_sea: 'reduced_v1'; + =namelist:jules_sea_seaice=cdn_max_sea: 'limited','reduced_v1'; + =namelist:jules_sea_seaice=u_cdn_hw: 'reduced_v1'; + =namelist:jules_sea_seaice=u_cdn_max: 'reduced_v1'; +value-titles=No special treatment of drag at high winds, + =The drag at high winds is capped, + =The drag at high winds is reduced over a range of speeds +values='null','limited','reduced_v1' + +[namelist:jules_sea_seaice=iseasurfalg] +compulsory=true +description=Algorithm for surface exchange over the sea +!enumeration=true +help=The most basic option for surface transfer at the sea surface + =consists of a specification of Charnocks coefficient for the + =momentum roughness length, including the aerodynamically smooth + =contribution in light winds, and a fixed thermal roughness length. + =Surface divergence theory allows for a variable thermal roughness + =length that follows the aerodynamicall smooth limit in light winds + =and decreases in stronger winds, giving a slower increase in the + =exchange coefficient for moisture as the wind rises. Historically, + =roughness lengths that depend on the friction velocity have not + =been iterated within the calculation of the Obukhov length, though + =this is more consistent: an iterative option is therefore provided. + =The COARE algorithm is based on a range of observations and exists + =in various forms. It features a dependence of Charnocks coefficient + =on the wind speed and a dependence of the thermal roughness length + =on the roughness Reynolds number. Extra parameters allow different + =versions of the algorithm to be used. +sort-key=Panel-C09 +trigger=namelist:jules_sea_seaice=z0m_specified: 'specified_roughness'; + =namelist:jules_sea_seaice=z0h_specified: 'specified_roughness'; +value-titles="Fixed values of roughness length for momentum and heat", + ="Fixed value of Charnock's coefficient with thermal + =roughness from surface divergence theory (non-iterative)", + ="Roughness lengths follow functional forms of the COARE + =algorithm" +values='specified_roughness','surf_div','coare' + +[namelist:jules_sea_seaice=kappa_seasurf] +compulsory=false +description=Thermal conductivity of sea-water (W / m / K) +!kind=default +sort-key=Panel-C11 +type=real + +[namelist:jules_sea_seaice=kappai] +compulsory=false +description=Thermal conductivity of sea-ice (W / m / K) +!kind=default +sort-key=Panel-C12 +type=real + +[namelist:jules_sea_seaice=kappai_snow] +compulsory=false +description=Thermal conductivity of snow on zero layer sea-ice (W / m / K) +!kind=default +sort-key=Panel-C13 +type=real + +[namelist:jules_sea_seaice=l_10m_neut] +compulsory=true +description=Logical for using neutral 10m wind speed to calculate the Charnock coefficient for sea points +!kind=default +sort-key=Panel-C08 +type=logical + +[namelist:jules_sea_seaice=l_iceformdrag_lupkes] +compulsory=true +description=Switch for diagnostic form drag following Lupkes et al. (2012) + =and Lupkes & Gryanik (2015) +!kind=default +sort-key=Panel-C07 +trigger=namelist:jules_sea_seaice=l_stability_lupkes: .true.; +type=logical + +[namelist:jules_sea_seaice=l_sice_heatflux] +compulsory=true +description=Do semi-implicit update of ti for sea-ice +!kind=default +sort-key=Panel-C10 +type=logical + +[namelist:jules_sea_seaice=l_stability_lupkes] +compulsory=true +description=Switch to include the stability dependence in the parametrization + =of ice form drag +!kind=default +sort-key=Panel-C07a +type=logical + +[namelist:jules_sea_seaice=l_use_dtstar_sea] +compulsory=true +description=Update the sea-surface temperature assuming a slab ocean with + = heat capacity given by namelist:jules_sea_seaice=hcap_sea +!kind=default +sort-key=Panel-C14 +trigger=namelist:jules_sea_seaice=hcap_sea: .true.; +type=logical + +[namelist:jules_sea_seaice=nice] +compulsory=true +description=Number of sea ice categories +help=The number of sea ice categories. This is normally 1 unless the model is + = coupled to a sea ice model when this is normally 5. This namelist + = entry is used to populate the nice variable in + = jules_control_init_mod.F90. All other subroutines should load + = nice from jules_control_init_mod and not from the surface + = namelist. +!kind=default +range=1:99 +sort-key=Panel-C00a +type=integer + +[namelist:jules_sea_seaice=u_cdn_hw] +compulsory=true +description=Neutral wind speed where the drag attains the high wind value. +!kind=default +sort-key=Panel-C06c +type=real + +[namelist:jules_sea_seaice=u_cdn_max] +compulsory=true +description=Neutral wind speed where the drag begins to be reduced from the maximum. +!kind=default +sort-key=Panel-C06d +type=real + +[namelist:jules_sea_seaice=z0h_specified] +compulsory=true +description=Specified roughness length for scalars [m] +fail-if=this < 0 +help=Specified value held fixed throughout the run used for surface exchange + =of scalar fields such as heat and moisture +!kind=default +range=0.0:100.0 +sort-key=Panel-C09b +type=real + +[namelist:jules_sea_seaice=z0m_specified] +compulsory=true +description=Specified roughness length for momentum [m] +fail-if=this < 0 +help=Specified value held fixed throughout the run +!kind=default +range=0.0:100.0 +sort-key=Panel-C09a +type=real diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-snow/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-snow/vn3.1/rose-meta.conf new file mode 100644 index 000000000..5248b8caa --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-snow/vn3.1/rose-meta.conf @@ -0,0 +1,99 @@ +[namelist:jules_snow] +compulsory=true +ns=namelist/JULES Science Settings/jules_snow +sort-key=Section-A12k +title=Snow options +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html + +[namelist:jules_snow=can_clump] +compulsory=true +description=Clumping parameter for snow in the calculation of the albedo of plant canopies +fail-if=len(this) != namelist:jules_surface_types=npft; # A value must be given for each PFT + =all(this == 0) and namelist:jules_radiation=l_embedded_snow == '.true.' and any(namelist:jules_snow=cansnowpft == '.true.'); # Results in floating point exception if 0. Only used if can_model = 4, cansnowpft = TRUE on that tile and l_embedded_snow = TRUE. +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_snow/Radiation parameters +sort-key=Panel-D09 +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::can_clump + +[namelist:jules_snow=cansnowpft] +compulsory=false +description=Flag indicating whether snow can be held under the canopy of each PFT +fail-if=len(this) != namelist:jules_surface_types=npft; # A value must be given for each PFT +!kind=default +length=: +sort-key=Panel-D05 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::cansnowpft + +[namelist:jules_snow=i_basal_melting_opt] +compulsory=true +description=Option for melting at the base of the snow pack. +!enumeration=true +ns=namelist/JULES Science Settings/jules_snow/Other parameters +sort-key=Panel-D17 +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::i_basal_melting_opt +value-titles=No basal melting,Instantaneous basal melting +values=0,1 + +[namelist:jules_snow=i_grain_growth_opt] +compulsory=true +description=Option for rate of growth of snow grains. +!enumeration=true +ns=namelist/JULES Science Settings/jules_snow/Other parameters +sort-key=Panel-D04 +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::i_grain_growth_opt +value-titles=Marshall1989,Taillandier2007_ET +values=0,1 + +[namelist:jules_snow=i_relayer_opt] +compulsory=true +description=Option for method of relayering the snow pack in the multilayer scheme. +!enumeration=true +ns=namelist/JULES Science Settings/jules_snow/Other parameters +sort-key=Panel-D01e +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::i_relayer_opt +value-titles=Original Scheme,Relayer inverse of grain size +values=0,1 + +[namelist:jules_snow=n_lai_exposed] +compulsory=true +description=Shape parameter for distribution of leaf area within canopies used in calculation of snow albedo. +fail-if=len(this) != namelist:jules_surface_types=npft; # A value must be given for each PFT +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_snow/Radiation parameters +sort-key=Panel-D10 +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::n_lai_exposed + +[namelist:jules_snow=rho_snow_fresh] +compulsory=false +description=Density of fresh snow (kg m-3) +!kind=default +ns=namelist/JULES Science Settings/jules_snow/Other parameters +sort-key=Panel-D01b +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::rho_snow_fresh + +[namelist:jules_snow=unload_rate_u] +compulsory=true +description=Term proportional to wind speed in background unloading rate of snow on canopies +fail-if=len(this) != namelist:jules_surface_types=npft; # A value must be given for each PFT +!kind=default +length=: +ns=namelist/JULES Science Settings/jules_snow/Other parameters +sort-key=Panel-D13 +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_snow.nml.html#JULES_SNOW::unload_rate_u + +# Dummy page to force sort order for Snow other parameters +[namespace:snow_other] +ns=namelist/JULES Science Settings/jules_snow/Other parameters +sort-key=02 + +# Dummy page to force sort order for Snow radiation parameters +[namespace:snow_radiation] +ns=namelist/JULES Science Settings/jules_snow/Radiation parameters +sort-key=01 diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-soil/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-soil/vn3.1/rose-meta.conf new file mode 100644 index 000000000..49a87b62a --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-soil/vn3.1/rose-meta.conf @@ -0,0 +1,31 @@ +[namelist:jules_soil] +compulsory=true +ns=namelist/JULES Science Settings/jules_soil +sort-key=Section-A12j +title=Soil options +url=http://jules-lsm.github.io/latest/namelists/jules_soil.nml.html#namelist-JULES_SOIL + +[namelist:jules_soil=l_dpsids_dsdz] +compulsory=true +description=Calculate vertical gradient of soil suction with the assumption of linearity only for + =fractional saturation (consistent with the calculation of hydraulic conductivity) +!kind=default +sort-key=Panel-E03 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_soil.nml.html#JULES_SOIL::l_dpsids_dsdz + +[namelist:jules_soil=l_soil_sat_down] +compulsory=true +description=Direction of water in excess of saturation +!kind=default +sort-key=Panel-E04 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_soil.nml.html#JULES_SOIL::l_soil_sat_down + +[namelist:jules_soil=l_vg_soil] +compulsory=true +description=Switch for van Genuchten soil hydraulic model. +!kind=default +sort-key=Panel-E02 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_soil.nml.html#JULES_SOIL::l_vg_soil diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface-types/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface-types/vn3.1/rose-meta.conf new file mode 100644 index 000000000..42ff6a41f --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface-types/vn3.1/rose-meta.conf @@ -0,0 +1,125 @@ +[namelist:jules_surface_types] +compulsory=true +ns=namelist/JULES Surface Types/jules_surface_types +sort-key=Section-A12a +title=JULES Surface Types +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html + +[namelist:jules_surface_types=brd_leaf] +description=Pseudo level of broadleaf PFT +fail-if=this > namelist:jules_surface_types=npft; # Pseudo level must be less than or equal to npft +range=1: +sort-key=Panel-A1a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::brd_leaf + +[namelist:jules_surface_types=c3_grass] +description=Pseudo level of C3 grass PFT +fail-if=this > namelist:jules_surface_types=npft; # Pseudo level must be less than or equal to npft +range=1: +sort-key=Panel-A3a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::c3_grass + +[namelist:jules_surface_types=c4_grass] +description=Pseudo level of C4 grass PFT +fail-if=this > namelist:jules_surface_types=npft; # Pseudo level must be less than or equal to npft +range=1: +sort-key=Panel-A4a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::c4_grass + +[namelist:jules_surface_types=ice] +description=Pseudo level of ice surface type +fail-if=this > (namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg); # Pseudo level must be less than or equal to npft+nnvg + =this <= namelist:jules_surface_types=npft; # PFTs must be grouped together first with non-vegetated tiles following +range=1: +sort-key=Panel-A9a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::ice + +[namelist:jules_surface_types=lake] +description=Pseudo level of lake surface type +fail-if=this > (namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg); # Pseudo level must be less than or equal to npft+nnvg + =this <= namelist:jules_surface_types=npft; # PFTs must be grouped together first with non-vegetated tiles following +range=1: +sort-key=Panel-A7a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::lake + +[namelist:jules_surface_types=ndl_leaf] +description=Pseudo level of needleleaf PFT +fail-if=this > namelist:jules_surface_types=npft; # Pseudo level must be less than or equal to npft +range=1: +sort-key=Panel-A2a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::ndl_leaf + +[namelist:jules_surface_types=nnvg] +compulsory=true +description=The number of non-plant surface types to be modelled +range=1: +sort-key=Panel-A0b +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::nnvg + +[namelist:jules_surface_types=npft] +compulsory=true +description=The number of plant functional types to be modelled +range=0: +sort-key=Panel-A0a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::npft + +[namelist:jules_surface_types=shrub] +description=Pseudo level of shrub PFT +fail-if=this > namelist:jules_surface_types=npft; # Pseudo level must be less than or equal to npft +range=1: +sort-key=Panel-A5a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::shrub + +[namelist:jules_surface_types=soil] +compulsory=true +description=Pseudo level of soil surface type +fail-if=this > (namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg); # Pseudo level must be less than or equal to npft+nnvg + =this <= namelist:jules_surface_types=npft; # PFTs must be grouped together first with non-vegetated tiles following +range=1: +sort-key=Panel-A8 +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::soil + +[namelist:jules_surface_types=urban] +compulsory=true +description=Pseudo level of urban surface type +fail-if=this > (namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg); # Pseudo level must be less than or equal to npft+nnvg + =this <= namelist:jules_surface_types=npft; # PFTs must be grouped together first with non-vegetated tiles following + =this > 0 and (namelist:jules_surface_types=urban_roof > 0 or namelist:jules_surface_types=urban_canyon > 0); +range=-1,1: +sort-key=Panel-A6a +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::urban + +[namelist:jules_surface_types=urban_canyon] +compulsory=true +description=Pseudo level of urban canyon surface type +fail-if=this > namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg; # Pseudo level must be less than or equal to npft+nnvg + =this <= namelist:jules_surface_types=npft; # PFTs must be grouped together first with non-vegetated tiles following + =this > 0 and not (namelist:jules_surface_types=urban_roof > 0); # Both the canyon and roof surface type must be present + =not(this > 0) and namelist:jules_surface=l_urban2t == '.true.'; # When l_urban2t there must be a canyon and a roof surface type +range=-1,1: +sort-key=Panel-A6b +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::urban_canyon + +[namelist:jules_surface_types=urban_roof] +compulsory=true +description=Pseudo level of urban roof surface type +fail-if=this > namelist:jules_surface_types=npft + namelist:jules_surface_types=nnvg; # Pseudo level must be less than or equal to npft+nnvg + =this <= namelist:jules_surface_types=npft; # PFTs must be grouped together first with non-vegetated tiles following + =this > 0 and not (namelist:jules_surface_types=urban_canyon > 0); # Both the canyon and roof surface type must be present + =not(this > 0) and namelist:jules_surface=l_urban2t == '.true.'; # When l_urban2t there must be a canyon and a roof surface type +range=-1,1: +sort-key=Panel-A6c +type=integer +url=http://jules-lsm.github.io/latest/namelists/jules_surface_types.nml.html#JULES_SURFACE_TYPES::urban_roof diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface/HEAD/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface/HEAD/rose-meta.conf index 298fad335..210458cee 100644 --- a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface/HEAD/rose-meta.conf +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface/HEAD/rose-meta.conf @@ -6,9 +6,20 @@ sort-key=Section-A12e title=Surface options url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html +[namelist:jules_surface=all_tiles] +compulsory=true +description=Do calculations of tile properties on all tiles (except land ice) + =for all gridpoints even when the tile fraction is zero +!enumeration=true +sort-key=Panel-F10 +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::all_tiles +value-titles=Off,On +values=0,1 + [namelist:jules_surface=anthrop_heat_mean] compulsory=true description=Baseline mean anthropogenic heat flux for Flanner scheme +!kind=double sort-key=Panel-F03b type=real url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::anthrop_heat_mean @@ -23,11 +34,40 @@ url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SUR value-titles=DUKES fixed annual cycle, Flanner latitude-dependent annual and diurnal cycles values=0,1 +[namelist:jules_surface=beta1] +compulsory=true +description=Coupling coefficient for co-limitation +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=c +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::beta1 + +[namelist:jules_surface=beta2] +compulsory=true +description=Coupling coefficient for co-limitation +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=d +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::beta2 + +[namelist:jules_surface=beta_cnv_bl] +compulsory=true +description=Convective gustiness parameter in surface exchange +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +range=0.0: +sort-key=Panel-F11a +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::beta_cnv_bl + [namelist:jules_surface=cor_mo_iter] compulsory=true description=Corrections to Monin-Obukhov surface exchange calculation !enumeration=true sort-key=Panel-F11 +trigger=namelist:jules_surface=beta_cnv_bl: 4; url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::cor_mo_iter value-titles=Correct convective gustiness in low winds, =Correct U* in dust scheme, @@ -35,6 +75,20 @@ value-titles=Correct convective gustiness in low winds, =Improve initial guess (preferred) values=1,2,3,4 +[namelist:jules_surface=fd_hill_option] +compulsory=true +description=Orographic form drag formulation + =NOT AVAILABLE TO STANDALONE +!enumeration=true +help=The distributed version of turbulent orographic form drag can + =use steep or low hill formulations (the steep being the one used with + =effective roughness lengths), or the low hill formulation but with + =the resulting stress capped by that generated from the steep hill + =expression +sort-key=Panel-FX01c +value-titles=steep hill,low hill,capped low hill +values=0,1,2 + [namelist:jules_surface=fd_stability_dep] compulsory=true description=Stability dependence option for orographic form drag @@ -56,6 +110,7 @@ compulsory=true description=Orographic form drag option =NOT AVAILABLE TO STANDALONE !enumeration=true +fail-if=this != 0 and namelist:jules_model_environment=l_jules_parent == 0; # In standalone formdrag should be 0 help=Turbulent orographic form drag can be implemented either using =effective roughness lengths or as an explicit distributed drag profile. =This option is currently not available to standalone as there @@ -64,9 +119,72 @@ sort-key=Panel-FX01 trigger=namelist:jules_surface=orog_drag_param: 1,2; =namelist:jules_surface=fd_stability_dep: 1,2; =namelist:jules_surface=fd_hill_option: 2; + =namelist:run_stochastic=orog_drag_param_rp: 1,2; value-titles=No orographic stress,Effective roughness,Distributed Drag values=0,1,2 +[namelist:jules_surface=fwe_c3] +compulsory=true +description=Factor in expressions for limitation of photosynthesis + =by transport of products for C3 grass +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=e +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::fwe_c3 + +[namelist:jules_surface=fwe_c4] +compulsory=true +description=Factor in expressions for limitation of photosynthesis + =by transport of products for C4 grass +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=f +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::fwe_c4 + +[namelist:jules_surface=hleaf] +compulsory=true +description=Specific heat capacity of leaves (J / K / kg Carbon) +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=a +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::hleaf + +[namelist:jules_surface=hwood] +compulsory=true +description=Specific heat capacity of wood (J / K / kg Carbon) +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=b +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::hwood + +[namelist:jules_surface=i_modiscopt] +compulsory=true +description=Method of discretization in the surface layer + =NOT AVAILABLE TO STANDALONE +!enumeration=true +fail-if=this !=0 and namelist:jules_model_environment=l_jules_parent == 0; # In standalone i_modiscopt should be 0 +help=Should always be 0 (i.e. off) in standalone. +sort-key=Panel-FX02 +value-titles=Off,On +values=0,1 + +[namelist:jules_surface=iscrntdiag] +compulsory=true +description=Method of diagnosing the screen temperature +!enumeration=true +fail-if=(this == 2 or this == 3) and namelist:jules_model_environment=l_jules_parent == 0; # The preferred option in standalone is 0. The decoupled option specified is not recommended until driving JULES with a decoupled variable is fully tested. +sort-key=Panel-F12 +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::iscrntdiag +value-titles=No decoupling, + =Decoupled in very stable conditions, + =Decoupled with transitional effects, + =Decoupled (T & q) with transitional effects +values=0,1,2,3 + [namelist:jules_surface=l_anthrop_heat_src] compulsory=true description=Use anthropogenic heat source on urban surface types @@ -76,6 +194,66 @@ trigger=namelist:jules_surface=anthrop_heat_option: .true.; type=logical url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_anthrop_heat_src +[namelist:jules_surface=l_elev_land_ice] +compulsory=true +description=Use individual tiled bedrock sub-surfaces for land ice tiles +fail-if=this and any(namelist:jules_surface_types=elev_ice < 0) and any(namelist:jules_surface_types=elev_rock < 0); # At least one of elev_ice or elev_rock needs to be used (> 0). + =this and len(namelist:jules_surface_types=elev_ice) == 0 and len(namelist:jules_surface_types=elev_rock) == 0; # At least one of elev_ice or elev_rock needs to be used (> 0). + =this and any(namelist:jules_surface_types=elev_ice < 0) and len(namelist:jules_surface_types=elev_rock) == 0; # At least one of elev_ice or elev_rock needs to be used (> 0). + =this and len(namelist:jules_surface_types=elev_ice) == 0 and any(namelist:jules_surface_types=elev_rock < 0); # At least one of elev_ice or elev_rock needs to be used (> 0). +sort-key=Panel-F04 +trigger=namelist:jules_soil=dzsoil_elev: .true.; + =namelist:jules_snow=rho_firn_albedo: .true.; + =namelist:jules_snow=aicemax: .true.; + =namelist:jules_surface_types=elev_ice: .true.; + =namelist:jules_surface_types=elev_rock: .true.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_elev_land_ice + +[namelist:jules_surface=l_elev_lw_down] +compulsory=true +description=Adjust downward longwave radiation for elevated tiles +sort-key=Panel-F05 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_elev_lw_down + +[namelist:jules_surface=l_epot_corr] +compulsory=true +description=Use correction to calculation of potential evaporation +sort-key=Panel-F06 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_epot_corr + +[namelist:jules_surface=l_flake_model] +compulsory=true +description=Use the Flake model to simulate lakes. (Not yet ready to use with Irrigation or TRIFFID) +sort-key=Panel-F13 +trigger=namelist:jules_flake: .true.; + =namelist:jules_vegetation=l_triffid: .false.; + =namelist:jules_irrig=l_irrig_dmd: .false.; +type=logical + +[namelist:jules_surface=l_land_ice_imp] +compulsory=true +description=Use implicit numerics to update land ice temperatures +sort-key=Panel-F07 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_land_ice_imp + +[namelist:jules_surface=l_mo_buoyancy_calc] +compulsory=true +description=Switch for using interacting buoyancy in Monin-Obukhov calculation +sort-key=Panel-F14 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_mo_buoyancy_calc + +[namelist:jules_surface=l_point_data] +compulsory=true +description=Using point rainfall data +sort-key=Panel-F08 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_point_data + [namelist:jules_surface=l_urban2t] compulsory=true description=Switch for using the two-tile urban schemes (including MORUSES) @@ -86,6 +264,7 @@ trigger=namelist:jules_surface_types=urban_canyon: .true.; =namelist:jules_urban: .true.; =namelist:jules_urban=anthrop_heat_scale: .true.; =namelist:urban_properties: .true.; + =namelist:run_stochastic=z0_urban_mult_rp: .true. ; type=logical url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_urban2t @@ -93,14 +272,25 @@ url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SUR compulsory=true description=Enable soil roughness to be set from ancillary file =NOT AVAILABLE TO STANDALONE +fail-if=this == '.true.' and namelist:jules_model_environment=l_jules_parent == 0; # Variable roughness length of bare soil is currently not available to standalone. !kind=default sort-key=Panel-FX04 type=logical +[namelist:jules_surface=orog_drag_param] +compulsory=true +description=Drag coefficient for orographic form drag + =NOT AVAILABLE TO STANDALONE +!kind=double +range=0.01:10.0 +sort-key=Panel-FX01a +type=real + [namelist:jules_surface=srf_ex_cnv_gust] compulsory=true description=Include effect of convective downdraughts on surface exchange =NOT AVAILABLE TO STANDALONE +fail-if=this !=0 and namelist:jules_model_environment=l_jules_parent == 0; # This is not currently available to standalone. help=Surface exchange is affected by the mean wind, =eddies spanning the depth =of the boundary layer and eddies driven by convective downdraughts. @@ -113,3 +303,4 @@ help=Surface exchange is affected by the mean wind, =J. Climate,13,p. 402. !kind=default sort-key=Panel-FX03 +trigger=namelist:run_convection=cnv_cold_pools: 1; diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface/vn3.1/rose-meta.conf new file mode 100644 index 000000000..210458cee --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-surface/vn3.1/rose-meta.conf @@ -0,0 +1,306 @@ +[namelist:jules_surface] +compulsory=true +description=Options for surface parametrisations +ns=namelist/JULES Science Settings/jules_surface +sort-key=Section-A12e +title=Surface options +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html + +[namelist:jules_surface=all_tiles] +compulsory=true +description=Do calculations of tile properties on all tiles (except land ice) + =for all gridpoints even when the tile fraction is zero +!enumeration=true +sort-key=Panel-F10 +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::all_tiles +value-titles=Off,On +values=0,1 + +[namelist:jules_surface=anthrop_heat_mean] +compulsory=true +description=Baseline mean anthropogenic heat flux for Flanner scheme +!kind=double +sort-key=Panel-F03b +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::anthrop_heat_mean + +[namelist:jules_surface=anthrop_heat_option] +compulsory=true +description=Options for calculating anthropogenic heat +!enumeration=true +sort-key=Panel-F03a +trigger=namelist:jules_surface=anthrop_heat_mean: 1; +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::anthrop_heat_option +value-titles=DUKES fixed annual cycle, Flanner latitude-dependent annual and diurnal cycles +values=0,1 + +[namelist:jules_surface=beta1] +compulsory=true +description=Coupling coefficient for co-limitation +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=c +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::beta1 + +[namelist:jules_surface=beta2] +compulsory=true +description=Coupling coefficient for co-limitation +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=d +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::beta2 + +[namelist:jules_surface=beta_cnv_bl] +compulsory=true +description=Convective gustiness parameter in surface exchange +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +range=0.0: +sort-key=Panel-F11a +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::beta_cnv_bl + +[namelist:jules_surface=cor_mo_iter] +compulsory=true +description=Corrections to Monin-Obukhov surface exchange calculation +!enumeration=true +sort-key=Panel-F11 +trigger=namelist:jules_surface=beta_cnv_bl: 4; +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::cor_mo_iter +value-titles=Correct convective gustiness in low winds, + =Correct U* in dust scheme, + =Limit Obukhov length in low winds, + =Improve initial guess (preferred) +values=1,2,3,4 + +[namelist:jules_surface=fd_hill_option] +compulsory=true +description=Orographic form drag formulation + =NOT AVAILABLE TO STANDALONE +!enumeration=true +help=The distributed version of turbulent orographic form drag can + =use steep or low hill formulations (the steep being the one used with + =effective roughness lengths), or the low hill formulation but with + =the resulting stress capped by that generated from the steep hill + =expression +sort-key=Panel-FX01c +value-titles=steep hill,low hill,capped low hill +values=0,1,2 + +[namelist:jules_surface=fd_stability_dep] +compulsory=true +description=Stability dependence option for orographic form drag + =NOT AVAILABLE TO STANDALONE +!enumeration=true +help=Turbulent orographic form drag can be implemented either using + =effective roughness lengths or as a distributed drag profile + =dependent on the switch namelist:jules_surface=formdrag. + =This drag can either be applied without any stability dependence, + =or dependent on the surface to level 1 Richardson number, or for + =the distributed version, on a bulk Richardson number between the + =surface and the diagnosed middle-layer depth, h_m. +sort-key=Panel-FX01b +value-titles=Off,Surface Ri,Bulk Ri +values=0,1,2 + +[namelist:jules_surface=formdrag] +compulsory=true +description=Orographic form drag option + =NOT AVAILABLE TO STANDALONE +!enumeration=true +fail-if=this != 0 and namelist:jules_model_environment=l_jules_parent == 0; # In standalone formdrag should be 0 +help=Turbulent orographic form drag can be implemented either using + =effective roughness lengths or as an explicit distributed drag profile. + =This option is currently not available to standalone as there + =is no mechanism of providing the necessary ancillary data. +sort-key=Panel-FX01 +trigger=namelist:jules_surface=orog_drag_param: 1,2; + =namelist:jules_surface=fd_stability_dep: 1,2; + =namelist:jules_surface=fd_hill_option: 2; + =namelist:run_stochastic=orog_drag_param_rp: 1,2; +value-titles=No orographic stress,Effective roughness,Distributed Drag +values=0,1,2 + +[namelist:jules_surface=fwe_c3] +compulsory=true +description=Factor in expressions for limitation of photosynthesis + =by transport of products for C3 grass +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=e +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::fwe_c3 + +[namelist:jules_surface=fwe_c4] +compulsory=true +description=Factor in expressions for limitation of photosynthesis + =by transport of products for C4 grass +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=f +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::fwe_c4 + +[namelist:jules_surface=hleaf] +compulsory=true +description=Specific heat capacity of leaves (J / K / kg Carbon) +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=a +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::hleaf + +[namelist:jules_surface=hwood] +compulsory=true +description=Specific heat capacity of wood (J / K / kg Carbon) +!kind=double +ns=namelist/JULES Science Settings/jules_surface/Parameters +sort-key=b +type=real +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::hwood + +[namelist:jules_surface=i_modiscopt] +compulsory=true +description=Method of discretization in the surface layer + =NOT AVAILABLE TO STANDALONE +!enumeration=true +fail-if=this !=0 and namelist:jules_model_environment=l_jules_parent == 0; # In standalone i_modiscopt should be 0 +help=Should always be 0 (i.e. off) in standalone. +sort-key=Panel-FX02 +value-titles=Off,On +values=0,1 + +[namelist:jules_surface=iscrntdiag] +compulsory=true +description=Method of diagnosing the screen temperature +!enumeration=true +fail-if=(this == 2 or this == 3) and namelist:jules_model_environment=l_jules_parent == 0; # The preferred option in standalone is 0. The decoupled option specified is not recommended until driving JULES with a decoupled variable is fully tested. +sort-key=Panel-F12 +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::iscrntdiag +value-titles=No decoupling, + =Decoupled in very stable conditions, + =Decoupled with transitional effects, + =Decoupled (T & q) with transitional effects +values=0,1,2,3 + +[namelist:jules_surface=l_anthrop_heat_src] +compulsory=true +description=Use anthropogenic heat source on urban surface types +sort-key=Panel-F03 +trigger=namelist:jules_surface=anthrop_heat_option: .true.; + =namelist:jules_urban=anthrop_heat_scale: .true.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_anthrop_heat_src + +[namelist:jules_surface=l_elev_land_ice] +compulsory=true +description=Use individual tiled bedrock sub-surfaces for land ice tiles +fail-if=this and any(namelist:jules_surface_types=elev_ice < 0) and any(namelist:jules_surface_types=elev_rock < 0); # At least one of elev_ice or elev_rock needs to be used (> 0). + =this and len(namelist:jules_surface_types=elev_ice) == 0 and len(namelist:jules_surface_types=elev_rock) == 0; # At least one of elev_ice or elev_rock needs to be used (> 0). + =this and any(namelist:jules_surface_types=elev_ice < 0) and len(namelist:jules_surface_types=elev_rock) == 0; # At least one of elev_ice or elev_rock needs to be used (> 0). + =this and len(namelist:jules_surface_types=elev_ice) == 0 and any(namelist:jules_surface_types=elev_rock < 0); # At least one of elev_ice or elev_rock needs to be used (> 0). +sort-key=Panel-F04 +trigger=namelist:jules_soil=dzsoil_elev: .true.; + =namelist:jules_snow=rho_firn_albedo: .true.; + =namelist:jules_snow=aicemax: .true.; + =namelist:jules_surface_types=elev_ice: .true.; + =namelist:jules_surface_types=elev_rock: .true.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_elev_land_ice + +[namelist:jules_surface=l_elev_lw_down] +compulsory=true +description=Adjust downward longwave radiation for elevated tiles +sort-key=Panel-F05 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_elev_lw_down + +[namelist:jules_surface=l_epot_corr] +compulsory=true +description=Use correction to calculation of potential evaporation +sort-key=Panel-F06 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_epot_corr + +[namelist:jules_surface=l_flake_model] +compulsory=true +description=Use the Flake model to simulate lakes. (Not yet ready to use with Irrigation or TRIFFID) +sort-key=Panel-F13 +trigger=namelist:jules_flake: .true.; + =namelist:jules_vegetation=l_triffid: .false.; + =namelist:jules_irrig=l_irrig_dmd: .false.; +type=logical + +[namelist:jules_surface=l_land_ice_imp] +compulsory=true +description=Use implicit numerics to update land ice temperatures +sort-key=Panel-F07 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_land_ice_imp + +[namelist:jules_surface=l_mo_buoyancy_calc] +compulsory=true +description=Switch for using interacting buoyancy in Monin-Obukhov calculation +sort-key=Panel-F14 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_mo_buoyancy_calc + +[namelist:jules_surface=l_point_data] +compulsory=true +description=Using point rainfall data +sort-key=Panel-F08 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_point_data + +[namelist:jules_surface=l_urban2t] +compulsory=true +description=Switch for using the two-tile urban schemes (including MORUSES) +sort-key=Panel-F09 +trigger=namelist:jules_surface_types=urban_canyon: .true.; + =namelist:jules_surface_types=urban_roof: .true.; + =namelist:jules_surface_types=urban: .false.; + =namelist:jules_urban: .true.; + =namelist:jules_urban=anthrop_heat_scale: .true.; + =namelist:urban_properties: .true.; + =namelist:run_stochastic=z0_urban_mult_rp: .true. ; +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_surface.nml.html#JULES_SURFACE::l_urban2t + +[namelist:jules_surface=l_vary_z0m_soil] +compulsory=true +description=Enable soil roughness to be set from ancillary file + =NOT AVAILABLE TO STANDALONE +fail-if=this == '.true.' and namelist:jules_model_environment=l_jules_parent == 0; # Variable roughness length of bare soil is currently not available to standalone. +!kind=default +sort-key=Panel-FX04 +type=logical + +[namelist:jules_surface=orog_drag_param] +compulsory=true +description=Drag coefficient for orographic form drag + =NOT AVAILABLE TO STANDALONE +!kind=double +range=0.01:10.0 +sort-key=Panel-FX01a +type=real + +[namelist:jules_surface=srf_ex_cnv_gust] +compulsory=true +description=Include effect of convective downdraughts on surface exchange + =NOT AVAILABLE TO STANDALONE +fail-if=this !=0 and namelist:jules_model_environment=l_jules_parent == 0; # This is not currently available to standalone. +help=Surface exchange is affected by the mean wind, + =eddies spanning the depth + =of the boundary layer and eddies driven by convective downdraughts. + =Originally in the UM only boundary layer eddies were considered. If + =convective downdraughts are included, + =the impact of boundary-layer + =eddies on surface exchange is reduced and convective eddies are + =explicitly included using a parametrization due to Redelsperger + =et al. (2000), + =J. Climate,13,p. 402. +!kind=default +sort-key=Panel-FX03 +trigger=namelist:run_convection=cnv_cold_pools: 1; diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-urban/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-urban/vn3.1/rose-meta.conf new file mode 100644 index 000000000..4f1e6fb27 --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-urban/vn3.1/rose-meta.conf @@ -0,0 +1,50 @@ +[namelist:jules_urban] +compulsory=true +description=Sets the options available for the two-tile urban schemes including + =MORUSES. For all other parameters that MORUSES does not + =provide and for any MORUSES parametrisations that are turned + =off, values from "Non-vegetated surface parameters" will be + =used instead. See help for more information. +ns=namelist/JULES Science Settings/jules_urban +sort-key=Section-A12o +title=Urban options +url=http://jules-lsm.github.io/latest/namelists/urban.nml.html#namelist-JULES_URBAN + +[namelist:jules_urban=anthrop_heat_scale] +compulsory=true +description=Distribution scaling factor for anthropogenic heat flux +!kind=default +range=0:1 +type=real +url=http://jules-lsm.github.io/latest/namelists/urban.nml.html#JULES_URBAN::anthrop_heat_scale + +[namelist:jules_urban=l_moruses_albedo] +compulsory=true +description=Use MORUSES parameterisation for effective canyon albedo (snow free) +type=logical +url=http://jules-lsm.github.io/latest/namelists/urban.nml.html#JULES_URBAN::l_moruses_albedo + +[namelist:jules_urban=l_moruses_emissivity] +compulsory=true +description=Use MORUSES parameterisation for effective canyon emissivity +type=logical +url=http://jules-lsm.github.io/latest/namelists/urban.nml.html#JULES_URBAN::l_moruses_emissivity + +[namelist:jules_urban=l_moruses_rough] +compulsory=true +description=Use MORUSES parameterisation for effective roughness length for heat +type=logical +url=http://jules-lsm.github.io/latest/namelists/urban.nml.html#JULES_URBAN::l_moruses_rough + +[namelist:jules_urban=l_moruses_storage] +compulsory=true +description=Use MORUSES parameterisation for thermal inertia and coupling with underlying soil +trigger=namelist:jules_urban=l_moruses_storage_thin: .true.; +type=logical +url=http://jules-lsm.github.io/latest/namelists/urban.nml.html#JULES_URBAN::l_moruses_storage + +[namelist:jules_urban=l_moruses_storage_thin] +compulsory=true +description=Use thin roofs (includes effects of insulation) +type=logical +url=http://jules-lsm.github.io/latest/namelists/urban.nml.html#JULES_URBAN::l_moruses_storage_thin diff --git a/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-vegetation/vn3.1/rose-meta.conf b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-vegetation/vn3.1/rose-meta.conf new file mode 100644 index 000000000..f59be621c --- /dev/null +++ b/interfaces/jules_interface/rose-meta/lfric-jules-shared/jules-vegetation/vn3.1/rose-meta.conf @@ -0,0 +1,34 @@ +[namelist:jules_vegetation] +compulsory=true +description=Options for vegetation parametrisations +ns=namelist/JULES Science Settings/jules_vegetation +sort-key=Section-A12f +title=Vegetation options +url=http://jules-lsm.github.io/latest/namelists/jules_vegetation.nml.html + +[namelist:jules_vegetation=can_rad_mod] +compulsory=true +description=Vegetation canopy radiation model +!enumeration=true +sort-key=Panel-I13 +url=http://jules-lsm.github.io/latest/namelists/jules_vegetation.nml.html#JULES_VEGETATION::can_rad_mod +value-titles=1: Single canopy layer, + =4: Multi-layer two stream approach, + =5: Multi-layer with Sunfleck penetration and sunlit and shaded leaves, + =6: Multi-layer with exponential decline in leaf N + +[namelist:jules_vegetation=l_limit_canhc] +compulsory=true +description=Logical for capping vegetation canopy areal thermal heat capacity +!kind=default +sort-key=Panel-I04 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_vegetation.nml.html#JULES_VEGETATION::l_limit_canhc + +[namelist:jules_vegetation=l_spec_veg_z0] +compulsory=true +description=Logical switch for setting explicit vegetation roughness lengths +!kind=default +sort-key=Panel-I05 +type=logical +url=http://jules-lsm.github.io/latest/namelists/jules_vegetation.nml.html#JULES_VEGETATION::l_spec_veg_z0 diff --git a/interfaces/jules_interface/source/algorithm/jules_exp_alg_mod.x90 b/interfaces/jules_interface/source/algorithm/jules_exp_alg_mod.x90 index 18e785d09..ee0bb5f8d 100644 --- a/interfaces/jules_interface/source/algorithm/jules_exp_alg_mod.x90 +++ b/interfaces/jules_interface/source/algorithm/jules_exp_alg_mod.x90 @@ -22,8 +22,8 @@ module jules_exp_alg_mod use microphysics_config_mod, only: microphysics_casim use um_sizes_init_mod, only: um_sizes_init - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use log_mod, only: log_event, LOG_LEVEL_DEBUG use mesh_mod, only: mesh_type @@ -64,7 +64,6 @@ contains !>@param[in] aerosol_fields Fields for aerosol scheme !>@param[in,out] recip_l_mo_sea Inverse Obukhov length over sea only !>@param[in,out] rhostar Surface density - !>@param[in,out] h_blend_orog Orographic blending height !>@param[in,out] t1_sd_2d StDev of level 1 temperature !>@param[in,out] q1_sd_2d StDev of level 1 humidity subroutine jules_exp_alg(modeldb, theta, mr_n, & @@ -73,7 +72,7 @@ contains turbulence_fields, convection_fields, & cloud_fields, surface_fields, soil_fields, & snow_fields, aerosol_fields, recip_l_mo_sea, & - rhostar, h_blend_orog, t1_sd_2d, q1_sd_2d) + rhostar, t1_sd_2d, q1_sd_2d) use psykal_lite_phys_mod, only: invoke_jules_exp_kernel_type use xios, only: xios_date, xios_get_current_date, & @@ -98,7 +97,6 @@ contains type( field_type ), intent( inout ) :: recip_l_mo_sea type( field_type ), intent( inout ) :: rhostar - type( field_type ), intent( inout ) :: h_blend_orog type( field_type ), intent( inout ) :: t1_sd_2d type( field_type ), intent( inout ) :: q1_sd_2d @@ -228,9 +226,10 @@ contains type(xios_date) :: datetime integer(i_def), save :: day_of_year, second_of_day + integer(tik) :: id - if ( subroutine_timers ) call timer('jules_exp_alg') - + if ( LPROF ) call start_timing( id, 'jules.explicit' ) + call log_event( 'slow_physics: Running explicit JULES layer', LOG_LEVEL_DEBUG ) ! Cannot pass null pointers to invoke calls. Therefore non-pointer variables @@ -376,7 +375,6 @@ contains call zh%copy_field_properties(recip_l_mo_sea) call zh%copy_field_properties(rhostar) - call zh%copy_field_properties(h_blend_orog) call zh%copy_field_properties(t1_sd_2d) call zh%copy_field_properties(q1_sd_2d) @@ -448,14 +446,14 @@ contains flux_e, flux_h, urbwrr, & urbhwr, urbhgt, urbztm, urbdisp, & rhostar, recip_l_mo_sea, & - h_blend_orog, t1_sd_2d, q1_sd_2d, & + t1_sd_2d, q1_sd_2d, & gross_prim_prod, z0h_eff, ocn_cpl_point, & stencil_depth) ! Switch UM back to columns call um_sizes_init(1_i_def) - if ( subroutine_timers ) call timer('jules_exp_alg') + if ( LPROF ) call stop_timing( id, 'jules.explicit' ) ! output JULES diagnostics if (write_diag .and. use_xios_io) then diff --git a/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90 b/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90 index 3ee3d7829..68241339a 100644 --- a/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90 +++ b/interfaces/jules_interface/source/algorithm/jules_extra_alg_mod.x90 @@ -13,9 +13,9 @@ module jules_extra_alg_mod use field_collection_mod, only: field_collection_type use mesh_mod, only: mesh_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer - use surface_config_mod, only: lake_water_conservation + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF + use surface_config_mod, only: lake_water_conservation ! xios output use io_config_mod, only: write_diag, use_xios_io @@ -148,8 +148,9 @@ contains type(mesh_type), pointer :: mesh => null() integer( kind=i_def ) :: ncells + integer( tik ) :: id - if ( subroutine_timers ) call timer('jules_extra_alg') + if ( LPROF ) call start_timing( id, 'jules.extra' ) ! Unpack precipitation fields call microphysics_fields%get_field('ls_rain', ls_rain) @@ -268,7 +269,7 @@ contains call um_sizes_init(1_i_def) - if ( subroutine_timers ) call timer('jules_extra_alg') + if ( LPROF ) call stop_timing( id, 'jules.extra' ) if (use_xios_io .and. write_diag) then diff --git a/interfaces/jules_interface/source/algorithm/jules_imp_alg_mod.x90 b/interfaces/jules_interface/source/algorithm/jules_imp_alg_mod.x90 index c3cbb3ca4..355b37f74 100644 --- a/interfaces/jules_interface/source/algorithm/jules_imp_alg_mod.x90 +++ b/interfaces/jules_interface/source/algorithm/jules_imp_alg_mod.x90 @@ -18,8 +18,8 @@ module jules_imp_alg_mod use mr_indices_mod, only: imr_ci, nummr use timestepping_config_mod, only: outer_iterations - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! xios output use io_config_mod, only: write_diag, use_xios_io, diagnostic_frequency use jules_imp_diags_mod, only: initialise_diags_for_jules_imp, & @@ -166,8 +166,9 @@ contains type( mesh_type ), pointer :: mesh => null() integer(i_def) :: loop, ncells + integer(tik) :: id - if ( subroutine_timers ) call timer("jules_imp_alg") + if ( LPROF ) call start_timing( id, 'jules.implicit' ) call log_event( 'Running implicit Jules', LOG_LEVEL_DEBUG ) @@ -304,8 +305,7 @@ contains surf_radnet, surf_lw_up, surf_lw_down,& ocn_cpl_point) ) - - if ( subroutine_timers ) call timer("jules_imp_alg") + if ( LPROF ) call stop_timing( id, 'jules.implicit' ) ! Output the BL diagnostics if (use_xios_io .and. write_diag .and. outer == outer_iterations) then diff --git a/interfaces/jules_interface/source/algorithm/jules_timestep_alg_mod.x90 b/interfaces/jules_interface/source/algorithm/jules_timestep_alg_mod.x90 index f529642ac..50a9db08c 100644 --- a/interfaces/jules_interface/source/algorithm/jules_timestep_alg_mod.x90 +++ b/interfaces/jules_interface/source/algorithm/jules_timestep_alg_mod.x90 @@ -218,7 +218,7 @@ contains ! For jules_exp_alg ! not required for standalone, but required for boundary layer - type( field_type ) :: recip_l_mo_sea, rhostar, h_blend_orog + type( field_type ) :: recip_l_mo_sea, rhostar type( field_type ) :: t1_sd_2d, q1_sd_2d ! For jules_imp_alg @@ -288,7 +288,7 @@ contains turbulence_fields, convection_fields, cloud_fields, & surface_fields, soil_fields, snow_fields, & aerosol_fields, recip_l_mo_sea, rhostar, & - h_blend_orog, t1_sd_2d, q1_sd_2d) + t1_sd_2d, q1_sd_2d) ! Fields set up for jules_imp ! ncells is set to 1 after jules_exp so needs to be reset diff --git a/interfaces/jules_interface/source/algorithm/rad_tile_alg_mod.x90 b/interfaces/jules_interface/source/algorithm/rad_tile_alg_mod.x90 index 63bb8386e..7e6731b4c 100644 --- a/interfaces/jules_interface/source/algorithm/rad_tile_alg_mod.x90 +++ b/interfaces/jules_interface/source/algorithm/rad_tile_alg_mod.x90 @@ -14,11 +14,11 @@ use function_space_mod, only: function_space_type use mesh_mod, only: mesh_type use constants_mod, only: r_def, i_def use empty_data_mod, only: empty_real_data -use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_ERROR -use timer_mod, only: timer +use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use jules_control_init_mod, only: n_surf_tile use sci_geometric_constants_mod, only: get_dz_at_wtheta use fs_continuity_mod, only: W3, Wtheta @@ -135,9 +135,9 @@ subroutine rad_tile_alg(tile_sw_direct_albedo, tile_sw_diffuse_albedo, & ! Grey LW surface albedo real( kind=r_def ) :: planet_lw_albedo + integer( tik ) :: id - - if ( subroutine_timers ) call timer('rad_tile_alg') + if ( LPROF ) call start_timing( id, 'jules.radiation' ) vector_space => function_space_collection%get_fs( & twod_mesh, 0, 0, W3, n_sw_band * n_surf_tile ) @@ -306,7 +306,7 @@ subroutine rad_tile_alg(tile_sw_direct_albedo, tile_sw_diffuse_albedo, & call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end if - if ( subroutine_timers ) call timer('rad_tile_alg') + if ( LPROF ) call stop_timing( id, 'jules.radiation' ) end subroutine rad_tile_alg end module rad_tile_alg_mod diff --git a/interfaces/jules_interface/source/diagnostics/jules_exp_diags_mod.f90 b/interfaces/jules_interface/source/diagnostics/jules_exp_diags_mod.f90 index 28c952446..4bac420e3 100644 --- a/interfaces/jules_interface/source/diagnostics/jules_exp_diags_mod.f90 +++ b/interfaces/jules_interface/source/diagnostics/jules_exp_diags_mod.f90 @@ -10,8 +10,8 @@ module jules_exp_diags_mod use constants_mod, only: l_def use field_mod, only: field_type use integer_field_mod, only: integer_field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field implicit none @@ -39,14 +39,15 @@ subroutine initialise_diags_for_jules_exp(z0h_eff, gross_prim_prod, & type( field_type ), intent(inout) :: z0h_eff type( field_type ), intent(inout) :: gross_prim_prod type( field_type ), intent(inout) :: soil_respiration + integer( tik ) :: id - if ( subroutine_timers ) call timer("jules_exp_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_exp' ) z0h_eff_flag = init_diag(z0h_eff, 'surface__z0h_eff') gross_prim_prod_flag = init_diag(gross_prim_prod, 'surface__gross_prim_prod') soil_respiration_flag = init_diag(soil_respiration, 'surface__soil_respiration') - if ( subroutine_timers ) call timer("jules_exp_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_exp' ) end subroutine initialise_diags_for_jules_exp @@ -79,9 +80,9 @@ subroutine output_diags_for_jules_exp(z0h_eff, tile_fraction, z0m_tile, z0m, & gc_tile, soil_respiration, ustar, & z0m_eff, canopy_height, leaf_area_index type( field_type ), intent(in) :: dust_flux + integer( tik ) :: id - - if ( subroutine_timers ) call timer("jules_exp_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_exp' ) ! Prognostic fields from surface collection call tile_fraction%write_field('surface__tile_fraction') @@ -101,7 +102,7 @@ subroutine output_diags_for_jules_exp(z0h_eff, tile_fraction, z0m_tile, z0m, & if (gross_prim_prod_flag) call gross_prim_prod%write_field() if (soil_respiration_flag) call soil_respiration%write_field() - if ( subroutine_timers ) call timer("jules_exp_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_exp' ) end subroutine output_diags_for_jules_exp end module jules_exp_diags_mod diff --git a/interfaces/jules_interface/source/diagnostics/jules_imp_diags_mod.x90 b/interfaces/jules_interface/source/diagnostics/jules_imp_diags_mod.x90 index 5dc8ae284..13a36d4bf 100644 --- a/interfaces/jules_interface/source/diagnostics/jules_imp_diags_mod.x90 +++ b/interfaces/jules_interface/source/diagnostics/jules_imp_diags_mod.x90 @@ -7,14 +7,14 @@ module jules_imp_diags_mod - use constants_mod, only: l_def - use field_mod, only: field_type - use jules_control_init_mod, only: n_surf_tile, n_land_tile + use constants_mod, only: l_def + use field_mod, only: field_type + use jules_control_init_mod, only: n_surf_tile, n_land_tile use sci_weighted_ave_kernel_mod, only: weighted_ave_kernel_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF - use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field, & + use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field, & samp_diag => diagnostic_to_be_sampled implicit none @@ -260,8 +260,9 @@ contains ! Local variables type( field_type ) :: land_surface_temperature, grid_canopy_evap, & grid_surface_temperature, grid_latent_heat, grid_sublimation + integer( tik ) :: id - if ( subroutine_timers ) call timer("jules_imp_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_imp' ) ! Output prognostic fields - always output these on 2nd loop if (loop == 2) then @@ -341,7 +342,7 @@ contains end if - if ( subroutine_timers ) call timer("jules_imp_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_imp' ) end subroutine output_diags_for_jules_imp end module jules_imp_diags_mod diff --git a/interfaces/jules_interface/source/diagnostics/jules_seaice_diags_mod.x90 b/interfaces/jules_interface/source/diagnostics/jules_seaice_diags_mod.x90 index b7b796462..1129a35d7 100644 --- a/interfaces/jules_interface/source/diagnostics/jules_seaice_diags_mod.x90 +++ b/interfaces/jules_interface/source/diagnostics/jules_seaice_diags_mod.x90 @@ -8,8 +8,7 @@ module jules_seaice_diags_mod use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use jules_control_init_mod, only: first_sea_ice_tile, & n_sea_ice_tile @@ -48,8 +47,9 @@ contains ! Diagnostics locally computed here from other fields type( field_type ) :: sea_ice_fraction + integer( tik ) :: id - if ( subroutine_timers ) call timer("jules_seaice_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_seaice' ) ! Prognostic fields call sea_ice_thickness%write_field('seaice__sea_ice_thickness') @@ -65,7 +65,7 @@ contains first_sea_ice_tile, n_sea_ice_tile)) call sea_ice_fraction%write_field('seaice__sea_ice_fraction') - if ( subroutine_timers ) call timer("jules_seaice_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_seaice' ) end subroutine output_diags_for_jules_seaice end module jules_seaice_diags_mod diff --git a/interfaces/jules_interface/source/diagnostics/jules_snow_diags_mod.x90 b/interfaces/jules_interface/source/diagnostics/jules_snow_diags_mod.x90 index cc40f42a4..d48f4f014 100644 --- a/interfaces/jules_interface/source/diagnostics/jules_snow_diags_mod.x90 +++ b/interfaces/jules_interface/source/diagnostics/jules_snow_diags_mod.x90 @@ -7,13 +7,12 @@ module jules_snow_diags_mod - use constants_mod, only: l_def - use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use constants_mod, only: l_def + use field_mod, only: field_type + use timing_mod, only: start_timing, stop_timing, tik, LPROF use sci_weighted_ave_kernel_mod, only: weighted_ave_kernel_type - use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field + use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field implicit none @@ -44,15 +43,16 @@ contains ! Diagnostic fields to initialise type( field_type ), intent(inout) :: grid_snow_mass type( field_type ), intent(inout) :: grid_snowmelt + integer( tik ) :: id - if ( subroutine_timers ) call timer("jules_snow_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_snow' ) ! 2D fields grid_snow_mass_flag = init_diag(grid_snow_mass, 'snow__grid_snow_mass') if (grid_snow_mass_flag) call invoke( setval_c(grid_snow_mass, 0.0_r_def) ) grid_snowmelt_flag = init_diag(grid_snowmelt, 'snow__grid_snowmelt') - if ( subroutine_timers ) call timer("jules_snow_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_snow' ) end subroutine initialise_diags_for_jules_snow @@ -98,9 +98,9 @@ contains ! Diagnostics locally computed here from other fields type( field_type ), intent(inout) :: grid_snowmelt + integer( tik ) :: id - - if ( subroutine_timers ) call timer("jules_snow_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_snow' ) ! Prognostic fields call tile_snow_mass%write_field('snow__snow_mass') @@ -126,7 +126,7 @@ contains call grid_snow_mass%write_field() end if - if ( subroutine_timers ) call timer("jules_snow_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_snow' ) end subroutine output_diags_for_jules_snow end module jules_snow_diags_mod diff --git a/interfaces/jules_interface/source/diagnostics/jules_soil_diags_mod.x90 b/interfaces/jules_interface/source/diagnostics/jules_soil_diags_mod.x90 index 47a01a7a2..a3db5c361 100644 --- a/interfaces/jules_interface/source/diagnostics/jules_soil_diags_mod.x90 +++ b/interfaces/jules_interface/source/diagnostics/jules_soil_diags_mod.x90 @@ -7,12 +7,11 @@ module jules_soil_diags_mod - use constants_mod, only: l_def - use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use constants_mod, only: l_def + use field_mod, only: field_type + use timing_mod, only: start_timing, stop_timing, tik, LPROF use sci_weighted_ave_kernel_mod, only: weighted_ave_kernel_type - use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field + use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field implicit none @@ -55,8 +54,9 @@ contains type( field_type ), intent(inout) :: grid_canopy_water type( field_type ), intent(inout) :: throughfall type( field_type ), intent(inout) :: grid_throughfall + integer( tik ) :: id - if ( subroutine_timers ) call timer("jules_soil_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_soil' ) ! 2D fields soil_moisture_content_flag = init_diag(soil_moisture_content, 'soil__soil_moisture_content') @@ -72,7 +72,7 @@ contains ! Initialise field to that sea and sea-ice tiles have zero values if (throughfall_flag) call invoke(setval_c(throughfall, 0.0_r_def)) - if ( subroutine_timers ) call timer("jules_soil_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_soil' ) end subroutine initialise_diags_for_jules_soil @@ -126,8 +126,9 @@ contains ! Diagnostics locally computed here from other fields type( field_type ), intent(inout) :: grid_canopy_water type( field_type ), intent(inout) :: grid_throughfall + integer( tik ) :: id - if ( subroutine_timers ) call timer("jules_soil_diags") + if ( LPROF ) call start_timing( id, 'diags.jules_soil' ) ! Prognostic fields call canopy_water%write_field('surface__canopy_water') @@ -160,7 +161,7 @@ contains call surface_runoff%write_field('soil__surface_runoff') call sub_surface_runoff%write_field('soil__sub_surface_runoff') - if ( subroutine_timers ) call timer("jules_soil_diags") + if ( LPROF ) call stop_timing( id, 'diags.jules_soil' ) end subroutine output_diags_for_jules_soil end module jules_soil_diags_mod diff --git a/interfaces/jules_interface/source/kernel/jules_exp_kernel_mod.F90 b/interfaces/jules_interface/source/kernel/jules_exp_kernel_mod.F90 index 27f10473f..24e2aceb5 100644 --- a/interfaces/jules_interface/source/kernel/jules_exp_kernel_mod.F90 +++ b/interfaces/jules_interface/source/kernel/jules_exp_kernel_mod.F90 @@ -46,7 +46,7 @@ module jules_exp_kernel_mod !> type, public, extends(kernel_type) :: jules_exp_kernel_type private - type(arg_type) :: meta_args(109) = (/ & + type(arg_type) :: meta_args(108) = (/ & arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), &! theta_in_wth arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), &! exner_in_wth arg_type(GH_FIELD, GH_REAL, GH_READ, W3, STENCIL(REGION)), &! u_in_w3 @@ -150,7 +150,6 @@ module jules_exp_kernel_mod arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1), &! urbdisp arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1),&! rhostar arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1),&! recip_l_mo_sea - arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1),&! h_blend_orog arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1),&! t1_sd arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1),&! q1_sd arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1),&! diag__gross_prim_prod @@ -273,7 +272,6 @@ module jules_exp_kernel_mod !> @param[in] urbdisp Urban displacement height !> @param[in,out] rhostar_2d Surface density !> @param[in,out] recip_l_mo_sea_2d Inverse Obukhov length over sea only - !> @param[in,out] h_blend_orog_2d Orographic blending height !> @param[in,out] t1_sd_2d StDev of level 1 temperature !> @param[in,out] q1_sd_2d StDev of level 1 humidity !> @param[in,out] gross_prim_prod Diagnostic: Gross Primary Productivity @@ -424,7 +422,6 @@ subroutine jules_exp_code(nlayers, seg_len, seg_len_halo, & urbdisp, & rhostar_2d, & recip_l_mo_sea_2d, & - h_blend_orog_2d, & t1_sd_2d, & q1_sd_2d, & gross_prim_prod, & @@ -603,7 +600,6 @@ subroutine jules_exp_code(nlayers, seg_len, seg_len_halo, & z0m_eff, & ustar, & soil_moist_avail, & - h_blend_orog_2d, & recip_l_mo_sea_2d, & rhostar_2d, & t1_sd_2d, q1_sd_2d @@ -1678,7 +1674,6 @@ subroutine jules_exp_code(nlayers, seg_len, seg_len_halo, & ! variables passed to explicit BL rhostar_2d(map_2d(1,i)) = rhostar(i,1) recip_l_mo_sea_2d(map_2d(1,i)) = recip_l_mo_sea(i,1) - h_blend_orog_2d(map_2d(1,i)) = jules_vars%h_blend_orog_ij(i,1) t1_sd_2d(map_2d(1,i)) = t1_sd(i,1) q1_sd_2d(map_2d(1,i)) = q1_sd(i,1) diff --git a/interfaces/jules_interface/source/support/jules_control_init_mod.f90 b/interfaces/jules_interface/source/support/jules_control_init_mod.f90 index c19a936e9..c47a3d643 100644 --- a/interfaces/jules_interface/source/support/jules_control_init_mod.f90 +++ b/interfaces/jules_interface/source/support/jules_control_init_mod.f90 @@ -12,7 +12,7 @@ module jules_control_init_mod use jules_sea_seaice_config_mod, only : nice_in => nice ! Other LFRic modules used - use constants_mod, only : i_def + use constants_mod, only : i_def, imdi implicit none @@ -49,43 +49,54 @@ module jules_control_init_mod subroutine jules_control_init() ! LFRic namelists which have been read - use jules_surface_types_config_mod, only : npft_in => npft, & - nnvg_in => nnvg, & - brd_leaf_in => brd_leaf, & - ndl_leaf_in => ndl_leaf, & - c3_grass_in => c3_grass, & - c4_grass_in => c4_grass, & - shrub_in => shrub, & - urban_in => urban, & - urban_canyon_in => urban_canyon,& - urban_roof_in => urban_roof, & - lake_in => lake, & - soil_in => soil, & - ice_in => ice + use jules_model_environment_lfric_config_mod, only : & + l_jules_parent_in => l_jules_parent, & + l_jules_parent_lfric + use jules_surface_types_config_mod, only : & + npft_in => npft, & + nnvg_in => nnvg, & + brd_leaf_in => brd_leaf, & + ndl_leaf_in => ndl_leaf, & + c3_grass_in => c3_grass, & + c4_grass_in => c4_grass, & + shrub_in => shrub, & + urban_in => urban, & + urban_canyon_in => urban_canyon, & + urban_roof_in => urban_roof, & + lake_in => lake, & + soil_in => soil, & + ice_in => ice use section_choice_config_mod, only : surface, surface_jules ! UM/JULES modules containing things that need setting use ancil_info, only: jules_dim_cs1 => dim_cs1, nsurft - use atm_step_local, only: co2_dim_len, co2_dim_row, & - dim_cs1 + use atm_step_local, only: co2_dim_len, co2_dim_row, dim_cs1 use jules_sea_seaice_mod, only: nice, nice_use use jules_soil_mod, only: jules_sm_levels => sm_levels - use jules_surface_types_mod, only: npft, nnvg, ntype, brd_leaf, ndl_leaf, & - c3_grass, c4_grass, shrub, urban, & - urban_canyon, urban_roof, lake, & + use jules_surface_types_mod, only: npft, nnvg, ntype, brd_leaf, ndl_leaf, & + c3_grass, c4_grass, shrub, urban, & + urban_canyon, urban_roof, lake, & soil, ice use jules_vegetation_mod, only: l_triffid - use jules_model_environment_mod, only: lsm_id, jules + use jules_model_environment_mod, only: lsm_id, jules, & + check_jules_model_environment use nlsizes_namelist_mod, only: ntiles, sm_levels use jules_surface_types_mod, only: & - set_derived_variables_jules_surface_types, & + set_derived_variables_jules_surface_types, & print_nlist_jules_surface_types, check_jules_surface_types use land_tile_ids_mod, only: set_surface_type_ids - use log_mod, only : log_event, log_scratch_space, LOG_LEVEL_INFO + use log_mod, only : log_event, log_scratch_space, LOG_LEVEL_INFO, & + LOG_LEVEL_ERROR + + use section_choice_config_mod, only: surface, & + surface_jules implicit none + ! This allows l_jules_parent switch to remain private in JULES module + integer(kind=i_def) :: l_jules_parent_config = imdi + call log_event( 'jules_control_init', LOG_LEVEL_INFO ) ! ---------------------------------------------------------------- @@ -180,8 +191,25 @@ subroutine jules_control_init() co2_dim_len = 1 co2_dim_row = 1 - ! Initialise LSM to be JULES (other options do exist; CABLE, Rivers-only) - lsm_id = jules + ! ---------------------------------------------------------------- + ! JULES model environment settings + ! - contained in module jules_model_environment + ! ---------------------------------------------------------------- + + if (surface == surface_jules) then + ! Initialise LSM to be JULES (other options do exist; CABLE, Rivers-only) + lsm_id = jules + select case (l_jules_parent_in) + case(l_jules_parent_lfric) + l_jules_parent_config = 3 + case default + write( log_scratch_space, '(A)' ) 'Parent model not set to LFRic.' + call log_event( log_scratch_space, LOG_LEVEL_ERROR ) + end select + + ! Check the contents of the jules model environment module + call check_jules_model_environment(l_jules_parent_config) + end if end subroutine jules_control_init diff --git a/interfaces/jules_interface/source/support/jules_physics_init_mod.f90 b/interfaces/jules_interface/source/support/jules_physics_init_mod.f90 index 7b4153e1f..03322e49d 100644 --- a/interfaces/jules_interface/source/support/jules_physics_init_mod.f90 +++ b/interfaces/jules_interface/source/support/jules_physics_init_mod.f90 @@ -85,22 +85,42 @@ module jules_physics_init_mod i_relayer_opt_original, & i_relayer_opt_inverse use jules_surface_config_mod, only : & + all_tiles_in => all_tiles, & + all_tiles_off, all_tiles_on, & + beta1_in => beta1, beta2_in => beta2, & + beta_cnv_bl_in => beta_cnv_bl, & cor_mo_iter_in => cor_mo_iter, & cor_mo_iter_lim_oblen, & cor_mo_iter_improved, & + fwe_c3_in => fwe_c3, fwe_c4_in => fwe_c4, & + hleaf_in => hleaf, hwood_in => hwood, & srf_ex_cnv_gust_in => srf_ex_cnv_gust, & formdrag_in => formdrag, formdrag_none, & formdrag_eff_z0, formdrag_dist_drag, & + fd_hill_option_in => fd_hill_option, & + fd_hill_option_capped_lowhill, & fd_stability_dep_in => fd_stability_dep, & fd_stability_dep_none, & fd_stability_dep_surf_ri, & + i_modiscopt_in => i_modiscopt, & + i_modiscopt_on, & + iscrntdiag_in => iscrntdiag, & + iscrntdiag_decoupled_trans, & + l_epot_corr_in => l_epot_corr, & + l_land_ice_imp_in => l_land_ice_imp, & + l_mo_buoyancy_calc_in => l_mo_buoyancy_calc, & anthrop_heat_option_in => anthrop_heat_option, & anthrop_heat_option_dukes, & anthrop_heat_option_flanner, & anthrop_heat_mean_in => anthrop_heat_mean, & l_anthrop_heat_src_in => l_anthrop_heat_src, & l_urban2t_in => l_urban2t, & - l_vary_z0m_soil_in => l_vary_z0m_soil + l_vary_z0m_soil_in => l_vary_z0m_soil, & + orog_drag_param_in => orog_drag_param, & + l_flake_model_in => l_flake_model, & + l_elev_land_ice_in => l_elev_land_ice, & + l_elev_lw_down_in => l_elev_lw_down, & + l_point_data_in => l_point_data use jules_vegetation_config_mod, only : & can_rad_mod_in => can_rad_mod, & can_rad_mod_one, can_rad_mod_four, & @@ -215,14 +235,18 @@ subroutine jules_physics_init() q10_ch4_npp, q10_ch4_resps, const_ch4_npp, const_ch4_resps, & t0_ch4, ch4_cpow, tau_ch4, k2_ch4, rho_ch4, q10_mic_ch4, cue_ch4, & mu_ch4, frz_ch4, alpha_ch4, ch4_cpow, ev_ch4, q10_ev_ch4 - use jules_surface_mod, only: l_epot_corr, cor_mo_iter, iscrntdiag, & - srf_ex_cnv_gust, Limit_ObukhovL, ip_scrndecpl2, IP_SrfExWithCnv, & - fd_stability_dep, orog_drag_param, check_jules_surface, & - Improve_Initial_Guess, formdrag, beta_cnv_bl, fd_hill_option, & - i_modiscopt, l_land_ice_imp, no_drag, effective_z0, & - capped_lowhill, explicit_stress, l_anthrop_heat_src, l_urban2t, & - l_vary_z0m_soil, l_mo_buoyancy_calc, anthrop_heat_option, dukes, & - flanner, anthrop_heat_mean + use jules_surface_mod, only: & + check_jules_surface, print_nlist_jules_surface, all_tiles, & + cor_mo_iter, Limit_ObukhovL, Improve_Initial_Guess, beta_cnv_bl, & + fd_hill_option, capped_lowhill, & + fd_stability_dep, orog_drag_param, & + formdrag, no_drag, effective_z0, explicit_stress, i_modiscopt, & + iscrntdiag, ip_scrndecpl2, srf_ex_cnv_gust, IP_SrfExWithCnv, & + l_anthrop_heat_src, anthrop_heat_option, dukes, flanner, & + anthrop_heat_mean, l_urban2t, l_epot_corr, l_land_ice_imp, & + l_mo_buoyancy_calc, l_vary_z0m_soil, beta1, beta2, fwe_c3, fwe_c4, & + hwood, hleaf, l_flake_model, l_elev_land_ice, l_elev_lw_down, & + l_point_data use jules_rivers_mod, only: lake_water_conserve_method, use_elake_surft use jules_urban_mod, only: anthrop_heat_scale, l_moruses_albedo, & l_moruses_emissivity, l_moruses_rough, l_moruses_storage, & @@ -472,21 +496,32 @@ subroutine jules_physics_init() ! ---------------------------------------------------------------- ! JULES surface settings - contained in module jules_surface ! ---------------------------------------------------------------- - anthrop_heat_mean = anthrop_heat_mean_in + anthrop_heat_mean = real(anthrop_heat_mean_in, r_um) select case (anthrop_heat_option_in) case(anthrop_heat_option_dukes) anthrop_heat_option = dukes case(anthrop_heat_option_flanner) anthrop_heat_option = flanner end select - beta_cnv_bl = 0.04_r_um + select case (all_tiles_in) + case(all_tiles_off) + all_tiles = 0 + case(all_tiles_on) + all_tiles = 1 + end select + beta1 = real(beta1_in, r_um) + beta2 = real(beta2_in, r_um) + beta_cnv_bl = real(beta_cnv_bl_in, r_um) select case (cor_mo_iter_in) case(cor_mo_iter_lim_oblen) cor_mo_iter = Limit_ObukhovL case(cor_mo_iter_improved) cor_mo_iter = Improve_Initial_Guess end select - fd_hill_option = capped_lowhill + select case (fd_hill_option_in) + case(fd_hill_option_capped_lowhill) + fd_hill_option = capped_lowhill + end select select case (fd_stability_dep_in) case(fd_stability_dep_none) fd_stability_dep = 0 @@ -501,16 +536,31 @@ subroutine jules_physics_init() case(formdrag_dist_drag) formdrag = explicit_stress end select - i_modiscopt = 1 - iscrntdiag = ip_scrndecpl2 + fwe_c3 = real(fwe_c3_in, r_um) + fwe_c4 = real(fwe_c4_in, r_um) + hleaf = real(hleaf_in, r_um) + hwood = real(hwood_in, r_um) + ! Awaiting advice from John Edwards regarding off or other allowed options + select case (i_modiscopt_in) + case(i_modiscopt_on) + i_modiscopt = 1 + end select + select case (iscrntdiag_in) + case(iscrntdiag_decoupled_trans) + iscrntdiag = ip_scrndecpl2 + end select if (srf_ex_cnv_gust_in) srf_ex_cnv_gust = IP_SrfExWithCnv - l_epot_corr = .true. - l_land_ice_imp = .true. - l_mo_buoyancy_calc = .true. + l_epot_corr = l_epot_corr_in + l_land_ice_imp = l_land_ice_imp_in + l_mo_buoyancy_calc = l_mo_buoyancy_calc_in l_anthrop_heat_src = l_anthrop_heat_src_in l_urban2t = l_urban2t_in l_vary_z0m_soil = l_vary_z0m_soil_in - orog_drag_param = 0.15_r_um + l_flake_model = l_flake_model_in + l_elev_land_ice = l_elev_land_ice_in + l_elev_lw_down = l_elev_lw_down_in + l_point_data = l_point_data_in + orog_drag_param = real(orog_drag_param_in, r_um) lake_water_conserve_method = use_elake_surft ! The minimum sea ice fraction @@ -522,6 +572,7 @@ subroutine jules_physics_init() endif ! Check the contents of the JULES surface parameters module + call print_nlist_jules_surface() call check_jules_surface() ! ---------------------------------------------------------------- diff --git a/interfaces/physics_schemes_interface/build/pre_process_phys.mk b/interfaces/physics_schemes_interface/build/pre_process_phys.mk index c5300ca75..0644411c1 100644 --- a/interfaces/physics_schemes_interface/build/pre_process_phys.mk +++ b/interfaces/physics_schemes_interface/build/pre_process_phys.mk @@ -23,6 +23,7 @@ MACRO_ARGS := $(addprefix -D,$(PRE_PROCESS_MACROS)) ifeq ("$(TRANSMUTE_INCLUDE_METHOD)", "specify_include") # For CPU OMP method, we want specific files SOURCE_xu_FILES := $(foreach THE_FILE, $(PSYCLONE_PHYSICS_FILES), $(patsubst $(SOURCE_DIR)/%.F90, $(SOURCE_DIR)/%.xu90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).F90' -print))) + SOURCE_xu_FILES += $(foreach THE_FILE, $(PSYCLONE_PASS_NO_SCRIPT), $(patsubst $(SOURCE_DIR)/%.F90, $(SOURCE_DIR)/%.xu90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).F90' -print))) else ifeq ("$(TRANSMUTE_INCLUDE_METHOD)", "specify_exclude") # For the offload method, we want to filter out specific files, and psyclone the rest # We don't want to wildcard the whole working directory, this will cause problems. diff --git a/interfaces/physics_schemes_interface/build/psyclone_transmute.mk b/interfaces/physics_schemes_interface/build/psyclone_transmute.mk index c9571d7f7..55dab07a2 100644 --- a/interfaces/physics_schemes_interface/build/psyclone_transmute.mk +++ b/interfaces/physics_schemes_interface/build/psyclone_transmute.mk @@ -13,13 +13,19 @@ TRANSMUTE_INCLUDE_METHOD ?= specify_include # Set the DSL Method in use to collect the correct transformation files. DSL := transmute +# Set default PSyclone transmute command additional options +PSYCLONE_TRANSMUTE_EXTRAS ?= -l all +# + # Find the specific files we wish to pre-processed and PSyclone from physics source # Set our target dependency to the version of the file we are to generate after # the psycloning step. # ifeq ("$(TRANSMUTE_INCLUDE_METHOD)", "specify_include") # For CPU OMP method, we want specific files. - SOURCE_F_FILES := $(foreach THE_FILE, $(PSYCLONE_PHYSICS_FILES), $(patsubst $(SOURCE_DIR)/%.xu90, $(SOURCE_DIR)/%.f90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).xu90' -print))) + SOURCE_F_FILES_ALL := $(foreach THE_FILE, $(PSYCLONE_PHYSICS_FILES), $(patsubst $(SOURCE_DIR)/%.xu90, $(SOURCE_DIR)/%.f90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).xu90' -print))) + SOURCE_F_FILES_PASS := $(foreach THE_FILE, $(PSYCLONE_PASS_NO_SCRIPT), $(patsubst $(SOURCE_DIR)/%.xu90, $(SOURCE_DIR)/%.f90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).xu90' -print))) + SOURCE_F_FILES := $(filter-out $(SOURCE_F_FILES_PASS), $(SOURCE_F_FILES_ALL)) else ifeq ("$(TRANSMUTE_INCLUDE_METHOD)", "specify_exclude") # For the offload method, we want to filter out specific files, and do the rest. # We don't want to wildcard the whole working directory, this will cause problems. @@ -30,7 +36,9 @@ else ifeq ("$(TRANSMUTE_INCLUDE_METHOD)", "specify_exclude") EXTEND_DIR_FULL_PATH := $(foreach THE_DIRECTORY, $(PSYCLONE_DIRECTORIES), $(shell find $(SOURCE_DIR) -name $(THE_DIRECTORY) -print)) SOURCE_F_FILES_FULL := $(strip $(foreach THE_PSY_DIR, $(EXTEND_DIR_FULL_PATH), $(patsubst $(SOURCE_DIR)/%.xu90, $(SOURCE_DIR)/%.f90, $(shell find $(THE_PSY_DIR) -name '*.xu90' -print)))) SOURCE_EXCEPTION := $(strip $(foreach THE_FILE, $(PSYCLONE_PHYSICS_EXCEPTION), $(patsubst $(SOURCE_DIR)/%.xu90, $(SOURCE_DIR)/%.f90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).xu90' -print)))) - SOURCE_F_FILES := $(filter-out $(SOURCE_EXCEPTION), $(SOURCE_F_FILES_FULL)) + SOURCE_F_FILES_ALL := $(filter-out $(SOURCE_EXCEPTION), $(SOURCE_F_FILES_FULL)) + SOURCE_F_FILES_PASS := $(foreach THE_FILE, $(PSYCLONE_PASS_NO_SCRIPT), $(patsubst $(SOURCE_DIR)/%.xu90, $(SOURCE_DIR)/%.f90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).xu90' -print))) + SOURCE_F_FILES := $(filter-out $(SOURCE_F_FILES_PASS), $(SOURCE_F_FILES_ALL)) endif endif @@ -44,14 +52,15 @@ endif psyclone: $(SOURCE_F_FILES) # PSyclone files back into f90 files. + # Where an optimisation script exists for a specific file, use it. # $(SOURCE_DIR)/%.f90: $(SOURCE_DIR)/%.xu90 $(OPTIMISATION_PATH)/$(DSL)/%.py echo PSyclone with file override script $(OPTIMISATION_PATH_PSY)/$(DSL)/$*.py on $< - PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ - -l all \ + PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath $(OPTIMISATION_PATH)/$(DSL)):$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ -s $(OPTIMISATION_PATH_PSY)/$(DSL)/$*.py \ -o $(SOURCE_DIR)/$*.f90 \ + $(PSYCLONE_TRANSMUTE_EXTRAS) \ $< # Where a local optimisation script exists, use it. @@ -59,27 +68,18 @@ $(SOURCE_DIR)/%.f90: $(SOURCE_DIR)/%.xu90 $(OPTIMISATION_PATH)/$(DSL)/%.py .SECONDEXPANSION: $(SOURCE_DIR)/%.f90: $(SOURCE_DIR)/%.xu90 $$(dir $$(OPTIMISATION_PATH_PSY)/$$(DSL)/$$*)local.py echo PSyclone with local script $(dir $(OPTIMISATION_PATH_PSY)/$(DSL)/$*)local.py on $< - PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ - -l all \ + PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath $(OPTIMISATION_PATH)/$(DSL)):$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ -s $(dir $(OPTIMISATION_PATH_PSY)/$(DSL)/$*)local.py \ -o $(SOURCE_DIR)/$*.f90 \ + $(PSYCLONE_TRANSMUTE_EXTRAS) \ $< # Where a global optimisation script exists, use it. # $(SOURCE_DIR)/%.f90: $(SOURCE_DIR)/%.xu90 $(OPTIMISATION_PATH)/$(DSL)/global.py echo PSyclone with global script $(OPTIMISATION_PATH_PSY)/$(DSL)/global.py on $< - PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ - -l all \ + PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath $(OPTIMISATION_PATH)/$(DSL)):$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ -s $(OPTIMISATION_PATH_PSY)/$(DSL)/global.py \ -o $(SOURCE_DIR)/$*.f90 \ - $< - -# Where no optimisation script exists, don't use it. -# -$(SOURCE_DIR)/%.f90: $(SOURCE_DIR)/%.xu90 - echo PSyclone pass with no optimisation applied, OMP and Clauses removed on $< - PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ - -l all \ - -o $(SOURCE_DIR)/$*.f90 \ + $(PSYCLONE_TRANSMUTE_EXTRAS) \ $< diff --git a/interfaces/physics_schemes_interface/build/psyclone_transmute_pass.mk b/interfaces/physics_schemes_interface/build/psyclone_transmute_pass.mk new file mode 100644 index 000000000..29ca28d04 --- /dev/null +++ b/interfaces/physics_schemes_interface/build/psyclone_transmute_pass.mk @@ -0,0 +1,44 @@ +############################################################################## +# (c) Crown copyright 2025 Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + +# Default for file selection method for transformation files is for CPU OMP currently +# This should be overwritten in: +# rose-stem/site//common/suite_config_.cylc +# +TRANSMUTE_INCLUDE_METHOD ?= specify_include + +# Set the DSL Method in use to collect the correct transformation files. +DSL := transmute + +# Set default PSyclone transmute command additional options +PSYCLONE_TRANSMUTE_EXTRAS ?= -l all +# + +# Find the specific files we wish to pre-processed and PSyclone from physics source +# Set our target dependency to the version of the file we are to generate after +# the psycloning step. +# +# For CPU OMP method, we want specific files. +SOURCE_F_FILES_PASS := $(foreach THE_FILE, $(PSYCLONE_PASS_NO_SCRIPT), $(patsubst $(SOURCE_DIR)/%.xu90, $(SOURCE_DIR)/%.f90, $(shell find $(SOURCE_DIR) -name '$(THE_FILE).xu90' -print))) + +# Default make target for file +# +.PHONY: psyclone_pass + +# Call this target, expect these files to be done first +# +psyclone_pass: $(SOURCE_F_FILES_PASS) + + +# PSyclone files back into f90 files. +# Where no optimisation script exists, don't use it. +# +$(SOURCE_DIR)/%.f90: $(SOURCE_DIR)/%.xu90 + echo PSyclone pass with no optimisation applied, OMP and Clauses removed on $< + PYTHONPATH=$(LFRIC_BUILD)/psyclone:$(abspath ../../interfaces/physics_schemes_interface/build):$$PYTHONPATH psyclone \ + -o $(SOURCE_DIR)/$*.f90 \ + $(PSYCLONE_TRANSMUTE_EXTRAS) \ + $< diff --git a/interfaces/physics_schemes_interface/build/transmute_psytrans/tools.py b/interfaces/physics_schemes_interface/build/transmute_psytrans/tools.py new file mode 100644 index 000000000..35c1b1c32 --- /dev/null +++ b/interfaces/physics_schemes_interface/build/transmute_psytrans/tools.py @@ -0,0 +1,50 @@ +# ----------------------------------------------------------------------------- +# (C) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ----------------------------------------------------------------------------- +''' +Contains some functions which might assist in generating scripts, but otherwise +would not be used in the script actively. +''' + + +# Tool, not active part of script +def find_node_index(routine_children, find_lhs, find_rhs): + ''' + A tool to assist developers finding the index of a node to + use when spanning a parallel section. + You can use the variable name of the LHS and either the variable + name of the RHS (if it exists), or the name of the function used + on the RHS. + This is called with a list of routine_children inside a walk of the + routines in the PSyIR object. + ''' + for index, node in enumerate(routine_children): + list_of_attributes = [] + try: + list_of_attributes = node.walk(Assignment) + except AttributeError: + pass + + for assignment in list_of_attributes: + if str(assignment.lhs.name) == find_lhs: + found_rhs=False + print("#### New find ####") + print("found LHS") + print(index) + try: + print(assignment.rhs.ast) + if find_rhs in str(assignment.rhs.ast): + found_rhs = True + except: + pass + try: + if str(assignment.rhs.name) == find_rhs: + found_rhs = True + except: + pass + if found_rhs: + print("Found RHS - Y") + print(index) + break diff --git a/interfaces/physics_schemes_interface/build/transmute_psytrans/transmute_functions.py b/interfaces/physics_schemes_interface/build/transmute_psytrans/transmute_functions.py index c1263a78c..a6dc39106 100644 --- a/interfaces/physics_schemes_interface/build/transmute_psytrans/transmute_functions.py +++ b/interfaces/physics_schemes_interface/build/transmute_psytrans/transmute_functions.py @@ -9,13 +9,16 @@ ''' import logging import os +from itertools import dropwhile, takewhile from typing import Sequence, Optional, Tuple, Set from psyclone.psyir.nodes import ( + Node, Loop, Call, Assignment, Reference, + Return, OMPParallelDirective, OMPDoDirective, OMPParallelDoDirective, @@ -30,6 +33,7 @@ RoutineSymbol, ImportInterface, UnsupportedFortranType, + INTEGER_TYPE, CHARACTER_TYPE, ) from psyclone.transformations import ( @@ -599,3 +603,240 @@ def match_lhs_assignments(node, names): if assignment.lhs.name in names: lhs_names.append(assignment.lhs.name) return lhs_names + + +def match_call_args(node, names): + """ + Check if any symbol names in list `names` appear in the + the list of subroutine arguments and return those names. + Useful for handling false dependencies. + """ + call_args = [] + for call in node.walk(Call): + for arg in call.arguments: + if hasattr(arg, "name") and arg.name in names: + call_args.append(arg.name) + return call_args + + +def loop_replacement_of(routine_itr, + target_name: str, + init_at_start=True): + ''' + This transformation checks that the loop iterator we are on is the one + we want, and then changes it to be of length 1 instead - The intent + is to primarily target the UM j loops with this call, but it is + generic. + + Parameters + ---------- + routine_itr : Routine iteration from a loop which walks the psyir routines + target_name : A loop of a given type + init_at_start : Do we want a initialisation at the start? Default True. + + Returns + ---------- + None : Note the tree has been modified + ''' + + do_once = False + # Get the loops from the provided routine and walk + for loop in routine_itr.walk(Loop): + # if the loop is of the target type + if str(loop.loop_type) == target_name: + + # Only init once in the routine at the start + if not do_once and init_at_start: + parent = routine_itr + assign = Assignment.create( + Reference(loop.variable), + Literal("1", INTEGER_TYPE)) + parent.children.insert(0, assign) + do_once = True + + # Get a parent table reference to move the loop body + try: + parent_table = loop.parent.scope.symbol_table + except AttributeError as err: + parent_table = False + + # if the loop parent table is a valid reference + if parent_table: + parent_table.merge(loop.loop_body.symbol_table) + # Move the body of the loop after the loop + for statement in reversed(loop.loop_body.children): + loop.parent.addchild( + statement.detach(), + loop.position + 1) + tmp = loop.detach() # noqa: F841 + + +def add_omp_parallel_region( + start_node, + end_node, + *, + end_offset=0, + include_end=False, + ignore_loops=None, + loop_trans_options=None, +): + """Add OMPParallelDirective around a span of nodes and OMPDoDirective around loops + + A parallel region will be created from siblings of start_node up to + end_node. + + An end_offset may be used to add or remove nodes from the end of the region, + and loops to be ignored can be supplied through ignore_loops. + + If end_node is not a sibling of start_node, loops and directives should be + added up to the absolute position of end_node, although the interaction with + offsets and include_end may be unexpected. + """ + if ignore_loops in (None, [None]): + ignore_loops = [] + + schedule = start_node.siblings + + if end_offset != 0: + local_idx = end_node.siblings.index(end_node) + end_node = end_node.siblings[local_idx + end_offset] + + start_pos = start_node.abs_position + end_pos = end_node.abs_position + if include_end: + end_pos += 1 + + nodes_from_start = dropwhile(lambda node: node.abs_position < start_pos, schedule) + all_nodes = list(takewhile(lambda node: node.abs_position < end_pos, nodes_from_start)) + + OMP_PARALLEL_REGION_TRANS.apply( + all_nodes, + options={ + "node-type-check": False, + }, + ) + + for loop in start_node.parent.walk(Loop): + # Identify each loop in the OMPParallelDirective and add OMPDoDirective to outer loops + + # Don't attempt to nest parallel directives or loops outside the parallel region + if loop.ancestor(OMPDoDirective) is not None or loop.ancestor(OMPParallelDirective) is None: + continue + + if loop in ignore_loops: + continue + + # OMPDoDirective for outer loops inside OMPParallelDirective region + try: + OMP_DO_LOOP_TRANS_STATIC.apply( + loop, + options=loop_trans_options, + ) + except TransformationError as e: + logging.warning(e) + + +def remove_unspanable_nodes( + routine_itr, + timer_routine_names, + remove_loop_type, +): + ''' + A method to help reduce the number of nodes found in a routine list. + This will remove some nodes that we do not ever wish to parallelise over. + This includes: + * The first and last timer calipers from the list: timer_routine_names. + * Ideally the final, but any return statement. + * Any variables which have had their loops removed, and are initialised. + + Parameters + ---------- + routine_itr : Routine iteration from a loop which walks the psyir routines. + timer_routine_names : Timer caliper list of names. + remove_loop_type : lhs only holds the variable name, keep this simple. + + Returns + ---------- + Copy of node list: A list of nodes from the given routine without + the above nodes. + ''' + + routine_children = routine_itr.children + return_copy_span = [] + delete_node_indexes = [] + + # Remove calipers + for index, routine_child in enumerate(routine_children): + + for routine in routine_child.walk(Reference): + try: + if str(routine.name) in timer_routine_names: + delete_node_indexes.append(index) + break + except: # noqa: E722 + continue + + # Remove the return statement + for index in range((len(routine_children)-1), 0, -1): + # If the instance is a return, add it to the list of indexes and exit + if isinstance(routine_children[index], Return): + delete_node_indexes.append(index) + break + + # Remove indexes at the start until we get to the first non assignment loop + for index, routine_child in enumerate(routine_children): + # Check if it is an assignment + # If so check whether the lhs name is in the remove_loop_type list + if isinstance(routine_child, Assignment): + if str(routine_child.lhs.name) in remove_loop_type: + delete_node_indexes.append(index) + # Otherwise exit + elif index not in delete_node_indexes: + break + + # A safer way is to build up a list of elements to remove + # Then remove the elements all at once. + delete_node_indexes.sort() + for index, routine_child in enumerate(routine_children): + if index not in delete_node_indexes: + return_copy_span.append(routine_child) + + return return_copy_span + + +def get_ancestors( + node, node_type=Loop, inclusive=False, exclude=(), depth=None +): + """ + Lifted from PSyTran. + Get all ancestors of a Node with a given type. + + :arg node: the Node to search for ancestors of. + :type node: :py:class:`Node` + :kwarg node_type: the type of node to search for. + :type node_type: :py:class:`type` + :kwarg inclusive: if ``True``, the current node is included. + :type inclusive: :py:class:`bool` + :kwarg exclude: type(s) of node to exclude. + :type exclude: :py:class:`bool` + :kwarg depth: specify a depth for the ancestors to have. + :type depth: :py:class:`int` + + :returns: list of ancestors according to specifications. + :rtype: :py:class:`list` + """ + assert isinstance(node, Node), f"Expected a Node, not '{type(node)}'." + assert isinstance( + inclusive, bool + ), f"Expected a bool, not '{type(inclusive)}'." + assert isinstance(node_type, tuple) or issubclass(node_type, Node) + if depth is not None: + assert isinstance(depth, int), f"Expected an int, not '{type(depth)}'." + ancestors = [] + node = node.ancestor(node_type, excluding=exclude, include_self=inclusive) + while node is not None: + ancestors.append(node) + node = node.ancestor(node_type, excluding=exclude) + if depth is not None: + ancestors = [a for a in ancestors if a.depth == depth] + return ancestors diff --git a/interfaces/physics_schemes_interface/rose-meta/um-aerosol/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-aerosol/version30_31.py new file mode 100644 index 000000000..99148171b --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-aerosol/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-aerosol/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-aerosol/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-aerosol/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-aerosol/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-aerosol/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-aerosol/vn3.1/rose-meta.conf new file mode 100644 index 000000000..8fa4fa8fb --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-aerosol/vn3.1/rose-meta.conf @@ -0,0 +1,345 @@ +[namelist:aerosol] +compulsory=true +description=Aerosol parametrization +ns=namelist/Science/UM Aerosol +sort-key=Section-A03 +title=Aerosol + +[namelist:aerosol=aclw_file] +compulsory=true +description=LW file: aitken and insol acc modes +help=The full path to the file containing the look-up table for aitken modes + =and insoluble accumulation-mode aerosol optical properties in the + =longwave. +ns=namelist/Science/UM Aerosol +sort-key=Panel-B02 +!string_length=filename +type=character + +[namelist:aerosol=acsw_file] +compulsory=true +description=SW file: aitken and insol acc mode +help=The full path to the file containing the look-up table for aitken modes + =and insoluble accumulation-mode aerosol optical properties in the + =shortwave. +ns=namelist/Science/UM Aerosol +sort-key=Panel-B03 +!string_length=filename +type=character + +[namelist:aerosol=activation_scheme] +compulsory=true +description=Calculate Cloud Droplet Number using: + = a Jones method doi:10.1038/370450a0 + = b Constant CDNC field +!enumeration=true +help=The Jones method is an empirical relation used to estimate CDNC + =from GLOMAP-mode aerosol. + = + =Note that Jones in UM is compatible with the 7mode including dust option. +sort-key=Panel-C01 +value-titles=off,jones +values='off','jones' + +[namelist:aerosol=anlw_file] +compulsory=true +description=LW file: soluble accumulation mode +help=The full path to the file containing the look-up table for soluble + =accumulation-mode aerosol optical properties in the longwave. +ns=namelist/Science/UM Aerosol +sort-key=Panel-B04 +!string_length=filename +type=character + +[namelist:aerosol=answ_file] +compulsory=true +description=SW file: soluble accumulation mode +help=The full path to the file containing the look-up table for soluble + =accumulation-mode aerosol optical properties in the shortwave. +ns=namelist/Science/UM Aerosol +sort-key=Panel-B05 +!string_length=filename +type=character + +[namelist:aerosol=crlw_file] +compulsory=true +description=LW file: coarse-mode +help=The full path to the file containing the look-up table for coarse-mode + =aerosol optical properties in the longwave +ns=namelist/Science/UM Aerosol +sort-key=Panel-B06 +!string_length=filename +type=character + +[namelist:aerosol=crsw_file] +compulsory=true +description=SW file: coarse-mode +help=The full path to the file containing the look-up table for coarse-mode + =aerosol optical properties in the shortwave. +ns=namelist/Science/UM Aerosol +sort-key=Panel-B07 +!string_length=filename +type=character + +[namelist:aerosol=easyaerosol_cdnc] +compulsory=true +description=Include CDNC from EasyAerosol ancils +help=Cloud Droplet Number Concentrations will be read from an + =EasyAerosol climatology ancil and sent to the microphysics scheme +ns=namelist/Science/UM Aerosol +trigger=namelist:files=cloud_drop_no_conc_ancil_path: .true. ; +type=logical + +[namelist:aerosol=easyaerosol_lw] +compulsory=true +description=Include LW radiative effects from EasyAerosol ancils +help=Direct radiative effects from a climatology of aerosol optical properties + =that are sent directly to the longwave radiation scheme +ns=namelist/Science/UM Aerosol +trigger=namelist:files=easy_asymmetry_lw_ancil_path: .true. ; +type=logical + +[namelist:aerosol=easyaerosol_sw] +compulsory=true +description=Include SW radiative effects from EasyAerosol ancils +help=Direct radiative effects from a climatology of aerosol optical properties + =that are sent directly to the shortwave radiation scheme +ns=namelist/Science/UM Aerosol +trigger=namelist:files=easy_asymmetry_sw_ancil_path: .true. ; +type=logical + +[namelist:aerosol=emissions] +compulsory=true +description=Use GC3 (3D) or GC5 (2D) biomass emissions +!enumeration=true +help=Which emissions options to use + = + =GC3 uses 3D ancillaries for bc_biomass and om_biomass, + = and a high level ancillary for SO2 + = + =GC5 uses 2D ancillaries for bc_biomass and om_biomass, + = and uses all SO2 at low level +ns=namelist/Science/UM Aerosol +sort-key=Panel-A02 +trigger=namelist:files=emiss_bc_biomass_ancil_path: 'GC3'; + =namelist:files=emiss_om_biomass_ancil_path: 'GC3'; + =namelist:files=emiss_so2_high_ancil_path: 'GC3'; + =namelist:files=emiss_bc_biomass_hi_ancil_path: 'GC5'; + =namelist:files=emiss_bc_biomass_lo_ancil_path: 'GC5'; + =namelist:files=emiss_om_biomass_hi_ancil_path: 'GC5'; + =namelist:files=emiss_om_biomass_lo_ancil_path: 'GC5'; +value-titles=GC3,GC5 +values='GC3','GC5' + +[namelist:aerosol=glomap_mode] +compulsory=true +description=GLOMAP-mode aerosol scheme +!enumeration=true +help=These schemes use a two-moment modal representation of aerosols giving + =the number concentration of particles in each mode and the mass + =concentrations of the particle components. + = + =A 7-mode GLOMAP-mode configuration (Mode Setup 8, MS8) is the default. + =This has 4 soluble modes (Nucleation, Aitken, Accumulation and Coarse) and + =3 insoluble modes (Aitken, Accumulation and Coarse). 5 different + =components are represented: sulphate (in the form of H2SO4), organic + =matter, black carbon, sea salt and mineral dust. + = + =A 2-mode GLOMAP-mode configuration (Mode Setup 6, MS6) is also used to + =elove and transport dust aerosol only. This has two insoluble modes + =(Accumulation and Coarse). Only the dust component is represented. + = + =GLOMAP-mode aerosol fields and particle properties derived from these by + =either of the GLOMAP-mode schemes (or the combined option) + =can be used in conjunction with + =RADAER to provide optical properties for the radiation scheme. + = + =Choice of GLOMAP-mode aerosol scheme + = + =[Climatology]: GLOMAP-mode aerosol climatology scheme. + =-------------------------------------------------------------------------- + =This is a relatively fast aerosol scheme limited to calculating the cloud + =droplet number concentration and/or the particle properties needed for + =determining radiative effects.This scheme is driven by offline aerosol + =fields. + = + =[ukca]: GLOMAP-mode aerosol full UKCA scheme. + =-------------------------------------------------------------------------- + =This is a full prognostic aerosol scheme with aerosol pre-cursor chemistry + =provided by the UKCA Offline Oxidants chemistry scheme. + = + =[dust_and_clim]: + =-------------------------------------------------------------------------- + =GLOMAP-mode aerosol full UKCA scheme (MS6) with the remaining + =GLOMAP-mode aerosols obtained from the climatology scheme (MS8). + = + =[radaer_test]: + =-------------------------------------------------------------------------- + =A RADAER test option allows RADAER to be run without either scheme being + =active. Initial values of the aerosol and particle property fields will + =then be used instead. This option may be used for independent evaluation + =of RADAER or for troubleshooting during development. +ns=namelist/Science/UM Aerosol +sort-key=Panel-A01 +trigger=namelist:aerosol=activation_scheme: 'climatology','dust_and_clim' ; + =namelist:aerosol=l_radaer: 'climatology','ukca','dust_and_clim','radaer_test' ; + =namelist:aerosol=emissions: 'ukca' ; + =namelist:aerosol=horiz_d: 'ukca','dust_and_clim'; + =namelist:aerosol=us_am: 'ukca','dust_and_clim'; +value-titles=off,climatology,ukca,dust_and_clim,radaer_test +values='off','climatology','ukca','dust_and_clim','radaer_test' + +[namelist:aerosol=horiz_d] +compulsory=true +description=Global tuning parameter for horizontal flux +help=horiz_d is a simple tuning knob to enhance/decrease dust emissions +!kind=default +range=0:99.9 +sort-key=Panel-F01 +type=real + +[namelist:aerosol=l_radaer] +compulsory=true +description=Direct effect of climatology aerosols in RADAER +help=Direct effect of GLOMAP-mode aerosols (from UKCA or Climatology) in the + =radiation scheme, including aerosol optical depth. +ns=namelist/Science/UM Aerosol +sort-key=Panel-B01 +trigger=namelist:aerosol=aclw_file: .true. ; + =namelist:aerosol=acsw_file: .true. ; + =namelist:aerosol=anlw_file: .true. ; + =namelist:aerosol=answ_file: .true. ; + =namelist:aerosol=crlw_file: .true. ; + =namelist:aerosol=crsw_file: .true. ; + =namelist:aerosol=prec_file: .true. ; + =namelist:aerosol=n_radaer_step: .true. ; +type=logical + +[namelist:aerosol=murk] +compulsory=true +description=Use murk aerosol +help=Include the single species prognostic aerosol commonly known as murk +!kind=default +ns=namelist/Science/UM Aerosol +sort-key=Panel-E01 +trigger=namelist:aerosol=murk_prognostic: .true.; + =namelist:aerosol=murk_visibility: .true.; +type=logical + +[namelist:aerosol=murk_lbc] +compulsory=true +description=Apply lateral boundary conditions for murk +help=If true, lateral boundary conditions for murk will be read from file + = If false, a constant flux of murk at the boundary is assumed +!kind=default +ns=namelist/Science/UM Aerosol +sort-key=Panel-E02b +type=logical + +[namelist:aerosol=murk_prognostic] +compulsory=true +description=Emit, advect, mix and rainout the murk aerosol +help=If false, the murk field will be a static field provided by an ancillary + =If true, the murk field will arise due to emissions, and be processed + = via the transport, mixing and scavenging (rainout) schemes +!kind=default +ns=namelist/Science/UM Aerosol +sort-key=Panel-E02 +trigger=namelist:aerosol=murk_source_scaling: .true.; + =namelist:aerosol=murk_lbc: .true.; + =namelist:files=emiss_murk_ancil_path: .true.; +type=logical + +[namelist:aerosol=murk_source_scaling] +compulsory=true +description=Scaling factor applied to murk source +help=Combining pollutant emission inventories of different aerosol species + = into a single variable to describe the emission of murk is only accurate + = to some relative factor (there is no absolute value of murk). + =Therefore the source strength can be scaled with this variable to + = tune up or down the murk concentration appropriately. +!kind=default +ns=namelist/Science/UM Aerosol +range=0:9999 +sort-key=Panel-E02a +type=real + +[namelist:aerosol=murk_visibility] +compulsory=true +description=Use murk in the visibility calculation +help=If false, a constant value of 10microg/kg of aerosol will be used in + = visibility calculations + =If true, the murk field will be used in visibility calculations +!kind=default +ns=namelist/Science/UM Aerosol +sort-key=Panel-E03 +type=logical + +[namelist:aerosol=n_radaer_step] +compulsory=true +description=Number of radiation timesteps per radaer timestep +help=The radaer calculations may be done less frequently than + =every radiation timestep. Radaer calculations will + =be done on timesteps 1, 1+n_radaer_step*n_radstep, + = 1+(n_radaer_step*n_radstep)*2... +!kind=default +range=1: +sort-key=Panel-B01a +type=integer + +[namelist:aerosol=prec_file] +compulsory=true +description=File of pre-computed values +help=The full path to the file containing pre-computed constants, that are + =required when the GLOMAP-mode aerosol climatology interacts with RADAER. +ns=namelist/Science/UM Aerosol +sort-key=Panel-B08 +!string_length=filename +type=character + +[namelist:aerosol=sulphuric_strat_climatology] +compulsory=true +description=Sulphuric acid aerosol climatology +help=Include sulphuric acid aerosol in the stratosphere using a + =fixed column amount. +!kind=default +ns=namelist/Science/UM Aerosol +sort-key=Panel-D01 +trigger=namelist:aerosol=sulphuric_strat_column: .true.; +type=logical + +[namelist:aerosol=sulphuric_strat_column] +compulsory=true +description=Sulphuric acid aerosol stratospheric column amount kg/m2 +help=Total column amount in kg/m2 above the tropopause. + = + =This will be converted into a constant mixing ratio above the level + =of the tropopause determined from the WMO lapse rate criteria. + = + =A column mass of 1.86604e-6 kg/m2 is equal to the "Cusack" + =stratospheric aerosol climatolgy in the Unified Model. +!kind=default +ns=namelist/Science/UM Aerosol +sort-key=Panel-D02 +type=real + +[namelist:aerosol=ukca_mode_seg_size] +compulsory=false +description=Segment size for GLOMAP-mode +help=Number of segments used in ukca_aero_ctl. This is required to be greater + = than 1 to run GLOMAP with OpenMP multithreading. +!kind=default +ns=namelist/Science/UM Aerosol +sort-key=Panel-A01 +type=integer + +[namelist:aerosol=us_am] +compulsory=true +description=Multiplicative ustar correction +help=us_am is used to enhance U* to compensate for the fact that the + = thresholds in the code are for point-like U* rather than the grid-box + = mean +!kind=default +range=0:9.99 +sort-key=Panel-F02 +type=real diff --git a/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/version30_31.py new file mode 100644 index 000000000..1f6b2cd54 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/vn3.1/rose-meta.conf new file mode 100644 index 000000000..82f183e99 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-boundary_layer/vn3.1/rose-meta.conf @@ -0,0 +1,579 @@ +#============================================================================== +# BOUNDARY LAYER: +#============================================================================== + +[namelist:blayer] +compulsory=true +description=Boundary layer parametrization +ns=namelist/Science/UM Boundary layer +sort-key=Section-A04 +title=Boundary layer + +[namelist:blayer=a_ent_2] +compulsory=true +description=Empirical constant multiplying buoyancy reversal entrainment term +help=The entrainment parametrization includes a term dependent on the + =strength of any negative buoyancy generated through evaporative cooling + =on mixing between cloudy boundary layer air and cloud-free air entrained + =from above the boundary layer. LES studies suggest a value 0.056. +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:1.0 +sort-key=Panel-A08a +type=real + +[namelist:blayer=a_ent_shr] +compulsory=true +description=Empirical constant multiplying ustar entrainment term +help=The entrainment parametrization includes a term dependent on the + =friction velocity (ustar). The constant of proportionality had + =been 5.0 but the LES of Beare (2008) together with UKV case + =studies suggest a lower value would be more appropriate + =(Beare gives 1.6). +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:10.0 +sort-key=Panel-A08 +type=real + +[namelist:blayer=bl_levels] +description=Number of boundary layer levels +help=Typically only the levels in the lowest few kilometres of the + =atmosphere are passed to the boundary layer scheme, + =in order to save on + =CPU time. Depending on the choices in the Boundary Layer panel, + =the + =local scheme can be applicable to mixing processes in the free atmosphere + =above the boundary layer. +!kind=default +ns=namelist/Science/UM Boundary layer +range=1: +sort-key=Panel-A01 +type=integer + +[namelist:blayer=bl_mix_w] +compulsory=true +description=Allow BL scheme to mix vertical velocity +help=Typically this is used in convective scale applications when horizontal + =mixing via the Smagorinsky scheme is also included. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A13 +type=logical + +[namelist:blayer=bl_res_inv] +compulsory=true +description=Select method for representing flux across partly resolved inversions +!enumeration=true +help=When selected the thickness of the capping inversion is diagnosed + =and if it is thick enough to be partly resolved by the vertical grid, + =the turbulent fluxes across the top of the boundary layer are applied + =across the layers within the inversion via the boundary layer diffusion + =coefficients. Two options are available for how to calculate this flux. + =Either a specified cosine shape is used or else the flux is that + =required to bring the theta_vl profile to a target piecewise linear shape. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A15 +value-titles=None,Use a cosine flux profile, + =Use a target theta_vl profile +values='off','cosine_inv_flux','target_inv_profile' + +[namelist:blayer=c_gust] +compulsory=true +description=Constant in the wind gust diagnostic +help=Tunable parameter used in the calculation of the wind gust. + =For many years this was set to 4.0 but a value of 3.14 is + =more approriate. This affects both forms of the wind gust + =diagnostics, wind_gust and scale_dep_wind_gust. +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:10.0 +sort-key=Panel-A02b +type=real + +[namelist:blayer=cbl_mix_fac] +compulsory=true +description=Parameter to control convective BL stability function +help=Parameter to control mixing from the Ri-based scheme in convective + =boundary layers, varying from 'Conventional' (0.0) to 'Standard' (1.0) + =LEM functions +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:1.0 +sort-key=Panel-A02a +type=real + +[namelist:blayer=cbl_opt] +compulsory=true +description=Convective BL stability function +!enumeration=true +help=Three options are available for the stability functions for unstable + =(negative) Richardson numbers: those described as the "standard" and + ="conventional" subgrid models in the LES of Brown (1999), and an option + =to adjust between the previous two using a parameter 'cbl_mix_fac'. + =The conventional model gives significantly less mixing than the standard. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A02 +trigger=namelist:blayer=cbl_mix_fac: 'adjustable'; +value-titles=Conventional LEM,Standard LEM,Adjustable LEM +values='conventional','standard','adjustable' + +[namelist:blayer=dec_thres_cloud] +compulsory=true +description=Decoupling threshold for cloudy boundary layers +help=This is recommended to be set to 0.1 +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:1.0 +sort-key=Panel-A11a +type=real + +[namelist:blayer=dec_thres_cu] +compulsory=true +description=Decoupling threshold for cumulus +help=This is recommended to be set to 0.05 +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:1.0 +sort-key=Panel-A11b +type=real + +[namelist:blayer=dyn_diag] +compulsory=true +description=Shear driven BL diagnosis options +!enumeration=true +help=In situations where surface conditions are close to neutral and the + =land fraction is less than a half, + =the thermodynamic parcel ascent diagnosis of both cumulus and + =non-local boundary layers are over-ruled to leave turbulent mixing + =to be determined by the local Richardson number scheme only. + ="zi/L used over sea" gives problems when BL_LEVELS is high, + =therefore "zi/L revised over sea" corrects this. + ="zi/L used in Cumulus over sea" applies this only to points + =diagnosed with Cumulus and strictly for sea points (fland<0.01, + =cf 0.5). + ="Ri based" also overrides Cumulus diagnosis if + =Zh(Ri) > Zlcl+zhloc_depth_fac*(Zhpar-Zlcl). + =Note that here Ri accounts for gradient adjustment by the + =non-local scheme. This option further restricts a Cumulus diagnosis + =to allow for disruption of cumulus formation through vertical wind + =shear (diagnosed through a sub-critical Richardson number profile + =extending well into the cloud layer). Under these circumstances the + =non-local boundary layer scheme is allowed to mix up to the original + =parcel ascent top. + = + =Additionally, + =for all options (other than 0) the consistency of the provisional + =diagnosis of an unstable boundary layer in CONV_DIAG is checked + =against the surface flux diagnosed by the surface exchange routines. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A09 +trigger=namelist:blayer=zhloc_depth_fac: 'ri_based'; +value-titles=zi/L revised over sea,zi/L used in Cumulus over sea,Ri based +values='zi_l_sea','zi_l_cu','ri_based' + +[namelist:blayer=dzrad_disc_opt] +compulsory=true +description=Cloud-top radiatively-cooled layer discretization options +!enumeration=true +help=The buoyancy-flux integration used to find the depth of mixing in + =stratocumulus layers is sensitive to the assumed depth of the cloud-top + =radiative cooling. However, this layer is often poorly resolved + =in the vertical, and there are options for how to treat it when it + =is too shallow to represent well on the grid: + =1) Set the base of the radiatively-cooled layer to be at theta-level + = nt - 1. Note that the top of the layer (the Sc-top) is allowed + = to vary continuously between model-levels (from rho-level nt+1 + = to rho-level nt+2). So this option makes the depth vary between + = 1.5 and 2.5 model-levels deep, with a sudden jump when the Sc-top + = passes a rho-level and nt jumps up. + =2) Set the base of the radiatively-cooled layer to be 1.5 model-levels + = below the accurate Sc-top (interpolating smoothly between the + = model-level heights). + = + = Both of these options satisfy a requirement that the base of the + = cloud-top layer falls below theta-level nt (otherwise vertical + = gradients used in the buoyancy flux integration are ill-defined). + = Under both options, the layer depth is subsequently increased up to + = at least 100m (or the base of the cloud) if it is shallower than that. + = Option 2 also includes any SL and qw gradients occuring within the + = radiatively-cooled layer when calculating the buoyancy-flux + = integrated over it (these are ignored in option 1). +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A10 +value-titles=1) Set base of layer at theta-level nt-1, + =2) Set base of layer smoothly 1.5 model-levels below cloud-top +values='level_ntm1','smooth_1p5' + +[namelist:blayer=entr_smooth_dec] +compulsory=true +description=Smoothly reduce surface-driven entrainment when decoupling +!enumeration=true +help=Reduce the surface-driven contribution to cloud-top entrainment + =smoothly as the strength of the decoupling grows (currently linearly + =dependent on the "svl" difference between cloud and sub-cloud layers + =in the range 0.5 to 1K. + =The second option also smoothly reduces the height-scale used to + =compute w* (which scales the surface-driven non-local mixing) from the + =Sc-top height to the SML-top height as a function of decoupling strength. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A10 +value-titles=Off, + =Smoothly taper surface entrainment terms, + =Also smoothly blend from zh to zhsc in w* +values='off','on','taper_zh' + +[namelist:blayer=flux_bc_opt] +compulsory=true +description=Surface flux production +!enumeration=true +help=This switch allows the user to specify the surface fluxes and/or surface + =stresses as follows: + = + = 'interactive' Interactive fluxes calculated by JULES + = 'specified_scalars' Specified scalar fluxes (sensible and latent heat) + = that are then calculated explicitly (this option is not recommended + = with interactive radiation because Tstar for upward LW is estimated) + = Fluxes are specified in namelist:specified_surface=function_name_fluxes. + = 'specified_scalars_tstar' As above but with prescribed surface temperature. + = 'specified_tstar' Specified surface temperatures, but not surface scalar fluxes + = Temperatures are specified in namelist:specified_surface=function_name_sst. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A01 +trigger=namelist:specified_surface=function_name_fluxes: 'specified_scalars','specified_scalars_tstar'; + =namelist:specified_surface=function_name_sst: 'specified_scalars_tstar', 'specified_tstar'; +value-titles=Interactive fluxes, Specified scalar fluxes only, Specified scalar fluxes and surface temperature, + =Specified surface temperature +values='interactive','specified_scalars','specified_scalars_tstar','specified_tstar' + +[namelist:blayer=free_atm_mix] +compulsory=true +description=Free atmospheric turbulent mixing option +!enumeration=true +help=Relax to SHARPEST: the stable stability function requested relaxes + =towards the "SHARPEST" function with height above the surface, + =with a fixed height scale of 1km. If "Do not reduce mixing lengths + =above the BL top" is selected this option will also smoothly merge + =to the asymptotic mixing length by 3km above the surface. + = + =Corrected NTML is as the original but corrects the level + =(ntml_local) below which the boundary layer value is used. + =The final option extends this version to use interactively diagnosed + =turbulent layer depths throughout the atmospheric column. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A05 +value-titles=Relax to SHARPEST,Original with corrected NTML, + =Original with diagnosed turbulent layer depths +values='to_sharp','ntml_corrected','free_trop_layer' + +[namelist:blayer=fric_heating] +compulsory=true +description=Apply heating source from turbulence dissipation +help=The drag on the resolved scale flow exerted by the boundary layer + =turbulence parametrization should ultimately be dissipated as heat + =but unless this option is selected this heating is ignored. It is + =recommended to be implemented in all model versions. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A04 +type=logical + +[namelist:blayer=interp_local] +compulsory=true +description=Choice of interpolation method for buoyancy gradient in Ri +!enumeration=true +help=Due to the winds and scalar fields being on staggered vertical grids, + =vertical interpolation is required to calculate the local turbulent + =diffusivity (as a function of shear and static stability). + =There are multiple options for the order of calculation / which + =fields to interpolate: + = 1) Interpolate the vertical gradients of sl,qw from their native + = rho-levels to theta-levels, and calculate stability, dbdz, and Kh + = on theta-levels. + = This has the advantage that the stability calculation can + = use the cloud-fraction on its native grid. But a disadvantage + = is that, since the gradients have to be interpolated, + = sharp changes in qw in cloud-free air above cloud-top inversions + = get multiplied by the in-cloud buoyancy coefficients. + = This can lead to arguably spurious instability at cloud-top + = and hence large fluxes through cloud-capping inversions. + = 2) Calculate stability, dbdz, on rho-levels where the gradients of + = sl,qw are defined (using an interpolated cloud-fraction), + = and then interpolate dbdz onto theta-levels to calculate Kh. + = This avoids the problem with option (1) at cloud-top inversions, + = but introduces additional complexity regarding how to + = interpolate the cloud-fraction onto rho-levels. The method used + = is to estimate the volume fraction of the rho-level that is + = saturated, based on the cloud-fractions at the neighbouring + = theta-levels, combined with the gradient of total-water + = supersaturation qw - qsat(Tl) between the two levels. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A04 +value-titles=Interpolate sl and qw gradients to compute dbdz on theta-levels, + =Compute dbdz on rho-levels and then interpolate to theta-levels +values='gradients','cf_dbdz' + +[namelist:blayer=kprof_cu] +compulsory=true +description=Switch for non-local mixing across the LCL in cumulus +!enumeration=true +help=When this option is not used, a diagnosis of a cumulus regime means + =that BL mixing is cut-off at the LCL leaving the convection scheme + =to couple the cloud and sub-cloud layers. + =The main advantages of using the BL scheme to couple the layers are + =that it is diffusive and the solution is implicit. Thus it responds + =more effectively to processes acting to cause the layers to diverge. + =Essentially two methods of generating the BL diffusion coefficients + =across the LCL in cumulus are available, although using the buoyancy + =flux integration algorithm is currently recommended. The less + =restrictive version of that allows the mixed layer top to be + =below the LCL +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A11 +value-titles=Use the buoyancy flux integration algorithm, + =Use less restrictive buoyancy flux integration algorithm +values='buoy_integ','buoy_integ_low' + +[namelist:blayer=l_converge_ga] +compulsory=true +description=Use gradient adjustment depth-dependence in b-flux integration +help=Improve accuracy of mixed-layer depths found via buoyancy-flux integration, + =by accounting for sensitivity of gradient adjustment to the depth. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A10 +type=logical + +[namelist:blayer=l_use_sml_dsc_fixes] +compulsory=true +description=Misc. fixes to surface and stratocumulus mixed layer diagnosis +help=This switch fixes, or mitigates, inadequacies in the original coding of + =the diagnosis of “decoupling” (the vertical extent of the diffusion + =profiles) by making a number of changes to the calculation of non-local + =turbulent mixing, related to the surface and stratocumulus mixed layers, + =and their coupling / decoupling: + =a) Remove accidental adding on of a separately-calculated entrainment + = flux at the SML-top when already using buoyancy-flux integration to + = estimate the entrainment diffusivity + = (avoids double-counting the SML entrainment-flux under cumulus). + =b) Don't turn on ksurf_iterate when the "well-mixed" test only confirms + = a diagnosed elevated DSC-layer should not be recoupled with the SML + = (caused some inconsistent setting of variables). + =c) Include missing factor of von Karman's constant times rho in the + = surface-driven Kh profile where this is added onto the DSC top-driven + = Kh profile in the buoyancy-flux integration + = (caused inaccurate estimate of the buoyancy-flux integral used to + = find the SML-top height under coupled DSC-layers). + =d) Close loop-hole in logic that allows highly stably-stratified + = cloudy layers to be suddenly mixed into the SML if a DSC-layer is + = pre-diagnosed above them + = (this was causing the code to skip a crucial test on whether the + = cloudy-layer up to parcel-top had too strong negative buoyancy-flux + = to be well-mixed). + =e) When finding the max cloud-fraction at the top of a turbulent layer + = (SML or DSC) for the purpose of computing cloud-depth, + = buoyancy-reversal and other cloud-top properties, + = check at ntml+1 as well as ntml and ntml-1 + = (original code missed instances where the inversion has nearly + = risen to the next level and ntml+1 is by-far the cloudiest level). + =f) Use revised setting of SML / DSC variables under recoupling. + = The original version diagnoses where the DSC-layer has been recoupled + = with the SML based on whether the SML-top model-level was changed + = inside excf_nl_9c, but there are rare instances where this doesn't give + = the right answer and the SML and DSC variables get muddled. + = The new version is more fool-proof, using flags explicitly set + = to indicate what has happened inside excf_nl_9c. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A10 +type=logical + +[namelist:blayer=near_neut_z_on_l] +compulsory=true +description=Threshold value of z/l below which to diagnose shear-driven BL +help=This is recommended to be set to 1.6 +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:10.0 +sort-key=Panel-A09a +type=real + +[namelist:blayer=new_kcloudtop] +compulsory=true +description=Use less level-dependent radiative flux jump calculation +help=This logical implements a new method to identify the cloud top in the + =radiative flux profile that results in a radiative flux jump estimation + = that has been found to be less resolution sensitive. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A10 +type=logical + +[namelist:blayer=ng_stress] +compulsory=true +description=Options for the Brown and Grant (1997) non-local stress scheme +!enumeration=true +help=This switch allows the user to choose between different physics options + =for the non-local stress profile of Brown and Grant (1997). + =The options are: + =1) BG97_limited, the Brown and Grant (1997) non-local stress profile + =applied above the surface layer with a limit on the surface stress used + =to scale the stress profile to avoid unphysical values, + =2) BG97_original, the same as BG97_limited but with the stress profile + =applied across the whole boundary layer (as originally defined by + =Brown and Grant (1997)). +ns=namelist/Science/UM Boundary layer +value-titles=Limited stress applied above the surface layer, + =Limited stress applied over full boundary layer depth +values='BG97_limited','BG97_original' + +[namelist:blayer=noice_in_turb] +compulsory=true +description=Ignore cloud ice in the BL turbulence scheme +help=If enabled the BL scheme will ignore all cloud ice + =(water content, qcf, and fraction, cff) in its conserved variables + =and mixing calculations. Specifically this includes: + =1) the calculation of buoyancy + =2) the calculation of saturated humidity + =3) the definition of conserved variables + = (ie sL=T+gz/cp - Lv qcl and qT=qv+qcl) + =To do so would effectively assume the timescales for ice freezing/melting + =are slower than the turbulence timescales, which is true for larger + =particles but perhaps less so for small crystals. +!kind=default +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A14 +type=logical + +[namelist:blayer=num_sweeps_bflux] +compulsory=true +description=Number of iterations used to converge buoyancy-flux criteria +help=The depth reached by Decoupled StratoCumulus mixing + =(and the height reached by the Surface Mixed Layer under some regimes) + =is determined by setting it such-that the vertical integral of + =negative turbulent buoyancy-flux at the base of a DSC (or top of a SML) + =equals a set small fraction of the integral of positive buoyancy-flux + =within the DSC-layer (or SML). The DSC-base or SML-top height satisfying + =this criterion is found by repeatedly sub-dividing the interval between + =one height that is too low and another that is too high into 4. + =num_sweeps_bflux sets the number of times the sub-dividision is repeated, + =and so determines the accuracy of the solution for the mixed-layer depths; + =each additional iteration reduces the error by a factor of 4. +!kind=default +ns=namelist/Science/UM Boundary layer +range=3:12 +sort-key=Panel-A10 +type=integer + +[namelist:blayer=p_unstable] +compulsory=true +description=Parameter for implicit solver in unstable BL column +help=Using 1.0 is recommended. In general, + =the higher these values are, + =the more stable the scheme becomes. However, + =running with great nonlinear stability at an + =area which is not required (where a weakly + =nonlinear is problem is solved) results in lower accuracy. +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:100.0 +sort-key=Panel-A12 +type=real + +[namelist:blayer=reduce_fa_mix] +compulsory=true +description=Options for where to reduce the local diffusion coefficients +!enumeration=true +help=Switch to decide where to keep the diffusion coefficient calculated + =by the local Richardson number scheme. It is found beneficial to avoid + =spurious mixing across well-defined inversions, + =particularly for stratocumulus-capped boundary layers, + =by setting these to zero. + =It can also be appropriate to remove this local mixing across the + =lifting condensation level in cumulus-capped layers. + =If the boundary layer mixing is blending with the Smagorinsky subgrid + =turbulence scheme then the local coefficients are only reduced by + =applying the 1D weighting function, + =rather than set to zero. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A06 +value-titles=Reduce in the levels spanning inversions and the LCL in cumulus, + =Reduce in the levels spanning inversions +values='inv_and_cu_lcl','inv_only' + +[namelist:blayer=sbl_opt] +compulsory=true +description=Stable BL stability function +!enumeration=true +help=There are many options for stable stability function in the Richardson + =number scheme that reflect the range of tunings used in operational models. + =The potential functions in increasing order of mixing strength are: + =LEM, SHARPEST, Meso, Louis and Long tails + =although not all these options have been coded into the LFRic interface. + = + =The LEM stability functions (which shut down turblence completely at a + =critical Ri=0.25) give a stability dependence more relevant to + =large-eddy simulation. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A03 +value-titles=LEM,SHARPEST,SHARP-sea; Mes-land +values='lem','sharpest','sharp_sea_mes_land' + +[namelist:blayer=sc_diag_opt] +compulsory=true +description=Options for diagnosing stratocumulus layers +!enumeration=true +help=This switch controls how the boundary-layer scheme decides which + =level is the top of a stratocumulus layer + =(where the Sc-top entrainment flux is applied). + =The available options are: + = 0) Original code: diagnose Sc based on svl gradient at non-cumulus points + = but set to the conv_diag parcel top at shallow cumulus points. + = 1) As (0) but also set the Sc-top to the conv_diag parcel top at + = "deep" cumulus points. + = 2) At all cumulus points, diagnose Sc-top based on max total-water RH + = instead of using the conv_diag parcel top. + = 3) Diagnose Sc-top based on max total-water RH at all points + = instead of using the svl gradient. +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A10 +value-titles=Original svl gradient and shallow Cu-top method, + =Relax to use parcel top at all convection points, + =Use max total-water RH method at convection points, + =Use max total-water RH method at all points +values='orig','cu_relax','cu_rh_max','all_rh_max' + +[namelist:blayer=sg_orog_mixing] +compulsory=true +description=Option for treating unresolved drainage flows +!enumeration=true +help=Drainage flows often form in hilly areas as the air near the surface + =cools at night. Where these flows are on scales too small to be + =resolved their effects on vertical mixing (through induced wind shear) + =should be included. Two independent methods to do this have been coded. + =Currently these require the orographic stress (LAND_SURF panel) and GWD + =schemes to be switched on in order to have the necessary ancillary + =fields loaded. The subgrid shear options currently convert these into + =a mean slope using an empirical relationship derived for the UKV only, + =and so this is not recommended for any other model. These options + =include the shear in the calculation of the Richardson number and + =diffusion coefficients, + =with an additional option to enhance the mixing lengths. The other + =option is to relate the length of the SHARPEST tail to subgrid orography, + =following McCabe and Brown (2007). +ns=namelist/Science/UM Boundary layer +sort-key=Panel-A07 +value-titles=None,Subgrid shear plus enhanced mixing lengths +values='none','shear_plus_lambda' + +[namelist:blayer=zhloc_depth_fac] +compulsory=true +description=Fractional cloud height reached by local BL depth calculation +!kind=default +ns=namelist/Science/UM Boundary layer +range=0.0:1.0 +sort-key=Panel-A09a +type=real diff --git a/interfaces/physics_schemes_interface/rose-meta/um-chemistry/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-chemistry/version30_31.py new file mode 100644 index 000000000..0a1d9131c --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-chemistry/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-chemistry/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-chemistry/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-chemistry/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-chemistry/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-chemistry/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-chemistry/vn3.1/rose-meta.conf new file mode 100644 index 000000000..22d7661b7 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-chemistry/vn3.1/rose-meta.conf @@ -0,0 +1,292 @@ +[namelist:chemistry] +compulsory=true +description=Chemistry settings +ns=namelist/Science/UM Chemistry +sort-key=Section-A16 +title=Chemistry + +[namelist:chemistry=chem_scheme] +compulsory=true +description=Chemistry scheme +!enumeration=true +help=Choice of UKCA chemistry scheme + = + =Currently available schemes are: + = 'Offline oxidants' which is the default scheme used + = with GLOMAP_mode for proto-GAL + = 'Strattrop' which is a full Stratosphere+Troposphere scheme + = 'Strat_test' which only switches on selected components of Strattrop + = This will be retired when Strattrop is fully implemented. + = 'flexchem' which is a flexible scheme for planetary atmospheres. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A01 +trigger=namelist:files=emiss_c2h6_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_c3h8_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_c5h8_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_ch4_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_co_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_hcho_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_me2co_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_mecho_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_meoh_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_nh3_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_no_aircrft_ancil_path: 'strattrop', 'strat_test' ; + =namelist:files=emiss_no_ancil_path: 'strattrop', 'strat_test' ; + =namelist:chemistry=l_ukca_ro2_ntp: 'strattrop', 'strat_test' ; + =namelist:chemistry=l_ukca_asad_full: 'offline_ox', 'strattrop', 'strat_test' ; + =namelist:chemistry=i_ukca_chem_version: 'offline_ox', 'strattrop', 'strat_test' ; + =namelist:chemistry=l_ukca_quasinewton: 'strattrop', 'strat_test' ; + =namelist:chemistry=top_bdy_opt: 'strattrop', 'strat_test' ; + =namelist:chemistry=l_ukca_linox_scaling: 'strattrop', 'strat_test' ; + =namelist:chemistry=flexchem_opt: 'flexchem'; + =namelist:chemistry=photol_scheme: 'strattrop', 'strat_test' ; + =namelist:chemistry=chem_timestep: 'offline_ox', 'strattrop', 'strat_test' ; +value-titles=none,offline_ox,strattrop,strat_test,flexchem +values='none','offline_ox','strattrop','strat_test','flexchem' + +[namelist:chemistry=chem_timestep] +compulsory=true +description=Chemistry timestep (seconds) +help=The UKCA chemical solver may not be called at every timestep + = for all model configurations. chem_timestep is the timestep + = for the chemistry solver, and determines the interval + = between sucessive calls to the chemistry in units of + = model timesteps. This chemical timestep affects the photolysis + = and aerosol models as well as the chemical solver. + = + = The timestep is specified in seconds, and must be a multiple of the + = model dynamical timestep +ns=namelist/Science/UM Chemistry +range=1:10800 +sort-key=Panel-A02c +type=integer + +[namelist:chemistry=fastjx_dir] +compulsory=true +description=Directory pathname for Fast-JX input files +help=Location of files containing the cross-section and scatterrer + =data. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A08a +type=character + +[namelist:chemistry=fastjx_mode] +compulsory=true +description=Method above cut-off level +help=Above the cut off level there are 3 options: + = 1: 'only lookup table' + = 2: 'combination of Fast-JX and lookup tables' + = 3: 'Fast-JX' + = The recommended option is to 'Use Lookup Tables' above a pressure + = cut-off of 20 hPa. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A07b +!type=integer +value-titles=only lookup table,Fast-JX and lookup table,Fast-JX only +values=1,2,3 + +[namelist:chemistry=fastjx_numwavel] +compulsory=true +description=Number of wavelengths to be used +help=It is possible to choose 8, 12 or 18 wavelength bins for Fast-JX. + =The 18 wavelength version is the full Fast-JX version. + =Choosing 12 is only suitable for troposphere only models + =and drops cross sections for stratospheric species. + =The 8 bin version is a fast troposphere only version. + =The choice between the 8 and 12 bin versions is a trade off + =between accuracy and speed. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A07c +!type=integer +value-titles='8 wavelengths','12 wavelengths','18 wavelengths' +values=8,12,18 + +[namelist:chemistry=fastjx_prescutoff] +compulsory=true +description=Cut-off Pressure for tabulated photolysis +help=The "Cut-off Pressure for tabulated photolysis" + = can be used to specify the pressure level (in Pascals -Pa) above + = which a simplified look-up table approach can be used to compensate + = for the lower wavelength limit of this scheme. The recommended + = option is to 'Use Lookup Tables' above a pressure cut-off of 20 Pa. +ns=namelist/Science/UM Chemistry +range=0:9999.999 +sort-key=Panel-A07c +type=real + +[namelist:chemistry=fjx_scat_file] +compulsory=true +description=filename for Fast-JX scatterer file +help=Fast-JX scatterer file containing the required scatterer data. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A08b +type=character + +[namelist:chemistry=fjx_solar_file] +compulsory=true +description=filename for Fast-JX solar cycle file +help=Fast-JX spectral file containing the required solar cycle spectral + =and time series data. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A09b +type=character + +[namelist:chemistry=fjx_solcyc_months] +compulsory=true +description=Months in solar cycle file +help=Number of months of data available in the fjx_solar_file +ns=namelist/Science/UM Chemistry +sort-key=Panel-A09c +type=integer + +[namelist:chemistry=fjx_solcyc_type] +compulsory=true +description=Apply solar variability to photolysis scheme +help=This is available for Fast-JX, not the 2-D Photolysis scheme + =(0) No solar cycle + =(1) Solar flux follows an observed solar cycle from a + =specified start year for a certain number months, + =outside of these times repeated average cyle is used + =(2) A repeated average cycle is used for all times. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A09a +trigger=namelist:chemistry=fjx_solar_file: 1,2 ; + =namelist:chemistry=fjx_solcyc_months: 1,2 ; +!type=integer +value-titles=no solar cycle,observed,average +values=0,1,2 + +[namelist:chemistry=fjx_spec_file] +compulsory=true +description=Filename for Fast-JX spectral file +help=Fast-JX spectral file containing the required cross-sections. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A08c +type=character + +[namelist:chemistry=flexchem_opt] +compulsory=true +description=Select option for flexible chemistry +!enumeration=true +help=Options: + = - None (abundances prescribed by e.g. input files), + = - Burrows & Sharp (1999, ApJ) analytic abundances for hot Jupiters, +ns=namelist/Science/UM Chemistry +sort-key=Panel-A03a +value-titles=none, Burrows & Sharp (1999) +values='none', 'bs1999' + +[namelist:chemistry=i_chem_timestep_halvings] +compulsory=false +description=Number of halvings for ASAD chemistry timestep +fail-if=this < 0 or this > 5 ; + =# number of chemistry timestep halvings must be between 0 and 5 +help=The number of times the chemistry timestep chem_timestep value is halved + = in UKCA's ASAD chemistry solver. + = + = For large values of ukca_chem_seg_size, setting a positive value of + = i_chem_timestep_halvings can skip unnecessary calculations. +ns=namelist/Science/UM Chemistry +range=0:5 +sort-key=Panel-A02c +type=integer + +[namelist:chemistry=i_ukca_chem_version] +compulsory=true +description=Chemical mechanism version +help=This version number controls the values of the rates + =and reactions used in ASAD-based chemical mechanisms. +ns=namelist/Science/UM Chemistry +range=107: +sort-key=Panel-A02b +type=integer + +[namelist:chemistry=l_ukca_asad_full] +compulsory=true +description=Call ASAD chemical solver with the full domain +help=Use (True) to select passing full (MPI/ local) domain to the + = ASAD N-R solver. + = False will pass data as individual or group of columns. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A02a +type=logical + +[namelist:chemistry=l_ukca_linox_scaling] +compulsory=true +description=Equally distribute Lightning NOx emissions using LOG(p) +help=When True, this logical makes the UKCA Lightning NOx routine + =redistribute the Lightning NOx emissions in the vertical + =linearly using LOG(pressure) and uses the same NOx production + =efficiency for cloud-to-ground and cloud-to-cloud flashes. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A06a +trigger=namelist:chemistry=lightnox_scale_fac: true; +type=logical + +[namelist:chemistry=l_ukca_quasinewton] +compulsory=true +description=Use quasi-Newton method in Newton-Raphson solver step +help=Controls use of quasi-Newton method during the ASAD (Newton-Raphson) + =solver step to improve speed of convergence: + =False for no scheme, + =True for quasi-Newton Broyden method. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A04 +type=logical + +[namelist:chemistry=l_ukca_ro2_ntp] +compulsory=true +description=To remove transport of RO2 tracers +help=if True, turns peroxy radical (RO2) in StratTrop to non-transported + =variables instead of transported tracers +ns=namelist/Science/UM Chemistry +sort-key=Panel-A02 +type=logical + +[namelist:chemistry=lightnox_scale_fac] +compulsory=true +description=Lightning NOx emiss scale factor +help=Scaling factor for NOx emissions due to Lightning +ns=namelist/Science/UM Chemistry +range=0.0: +sort-key=Panel-A06b +type=real + +[namelist:chemistry=photol_scheme] +compulsory=true +description=Photolysis scheme +!enumeration=true +help=Choice of UKCA photolysis scheme + = Only available for 'Strattrop' Chemistry scheme currently. + =Currently available schemes are: + = 'Off': No photolysis scheme used + = 'Prescribed': Use prescribed or 'pseudo' rates - as lodged at vn1.2 + = 'FastJX': Use the Fast-JX scheme +ns=namelist/Science/UM Chemistry +sort-key=Panel-A07a +trigger=namelist:chemistry=fastjx_mode: 'fastjx' ; + =namelist:chemistry=fastjx_numwavel: 'fastjx' ; + =namelist:chemistry=fastjx_prescutoff: 'fastjx' ; + =namelist:chemistry=fastjx_dir: 'fastjx' ; + =namelist:chemistry=fjx_scat_file: 'fastjx' ; + =namelist:chemistry=fjx_solcyc_type: 'fastjx' ; + =namelist:chemistry=fjx_spec_file: 'fastjx' ; +value-titles=Off,Prescribed,FastJX +values='off','prescribed','fastjx' + +[namelist:chemistry=top_bdy_opt] +compulsory=true +description=Select method of treating top boundary for selected species +!enumeration=true +help=Options: Do nothing specific at the top, + = Overwrite top 2 levels with 3rd-highest level for all species except H2O, + = Overwrite top level with 2nd-highest level for all species, + = Impose top boundary condition derived from ACE-FTS for NO, CO, O3, + = Impose top boundary condition derived from ACE-FTS for NO, CO, O3, H2O. +ns=namelist/Science/UM Chemistry +sort-key=Panel-A05 +value-titles=Do not overwrite, Overwrite top 2 levels (except H2O), + = Overwrite only top level, Overwrite NO CO & O3 top level, + = Overwrite NO CO O3 and H2O top level +values='no_overwrt', 'overwrt_top_two_lev', 'overwrt_only_top_lev', + ='overwrt_co_no_o3_top', 'overwrt_co_no_o3_h2o_top' diff --git a/interfaces/physics_schemes_interface/rose-meta/um-cloud/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-cloud/version30_31.py new file mode 100644 index 000000000..ffd4efc4c --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-cloud/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-cloud/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-cloud/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-cloud/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-cloud/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-cloud/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-cloud/vn3.1/rose-meta.conf new file mode 100644 index 000000000..ed341bd31 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-cloud/vn3.1/rose-meta.conf @@ -0,0 +1,630 @@ +#============================================================================== +# CLOUD: +#============================================================================== + +[namelist:cloud] +compulsory=true +description=Cloud parametrization +ns=namelist/Science/UM Cloud +sort-key=Section-A05 +title=Cloud + +[namelist:cloud=cff_spread_rate] +compulsory=true +description=Ice cloud fraction spreading rate +help=When the effects of shear on falling ice cloud are either ignored + = or derived from model winds, + =this controls the rate at which ice + = cloud fraction spreads. +!kind=default +ns=namelist/Science/UM Cloud +range=0.0:1.0e-1 +sort-key=Panel-A04a +type=real + +[namelist:cloud=cld_fsd_hill] +compulsory=true +description=Whether to use the Hill scheme for fractional standard deviation of condensate +help=If true: uses the Hill et al (2015) parametrization of fractional standard deviation + = (FSD) of cloud condensate in both the microphysics and the radiation schemes. + =If false: uses the Boutle et al (2014) scheme for fractional standard deviation in the + = the microphysics and a time-and-space invariant value for radiation. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A06 +trigger=namelist:cloud=cloud_horizontal_liq_fsd: .false.; + =namelist:cloud=cloud_horizontal_ice_fsd: .false.; + =namelist:cloud=fsd_min_conv_frac: .true.; + =namelist:cloud=fsd_conv_const: .true.; + =namelist:cloud=fsd_nonconv_liq_const: .true.; + =namelist:cloud=fsd_nonconv_ice_const: .true.; +type=logical + +[namelist:cloud=cloud_call_b4_conv] +compulsory=true +description=Extra call to the large-scale-cloud scheme before convection +help=Switch to perform an extra call to the large-scale cloud scheme before the + = call to convection in atmos_physics2, to ensure the latest T,q,qcl,cf + = seen by convection are consistent with the cloud scheme assumptions. + = For PC2, this entails an extra call to PC2 checks and PC2 initiation + = before convection, and the application of advective pressure forcing + = which in the UM is controlled by the switch l_pc2_sl_advection. + = For diagnostic cloud schemes, this only updates the "latest" cloud + = fraction fields passed into convection; the primary fields for the cloud + = fractions are still calculated in ni_imp_ctl as usual. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A12 +type=logical + +[namelist:cloud=cloud_horizontal_ice_fsd] +compulsory=true +description=Relative standard deviation of ice cloud condensate +help=Defines the sub-grid ice cloud horizontal inhomogeneity using a single + =global value of the ice cloud condensate relative standard deviation + =(standard deviation / mean). +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A07 +type=real + +[namelist:cloud=cloud_horizontal_liq_fsd] +compulsory=true +description=Relative standard deviation of liquid cloud condensate +help=Defines the sub-grid liquid cloud horizontal inhomogeneity using a single + =global value of the liquid cloud condensate relative standard deviation + =(standard deviation / mean). +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A07 +type=real + +[namelist:cloud=cloud_pc2_tol] +compulsory=true +description=PC2 threshold liquid cloud fraction to retain cloud (RH < RHcrit) +help=When RH is below RHcrit, instances of liquid-cloud fraction below + =cloud_pc2_tol are reset to zero at the end of each timestep. + =Also instances of liquid-cloud fraction above 1 - cloud_pc2_tol + =are reset to 1. + =This threshold is also used to determine when to initiate cloud + =from clear-sky (or holes in cloud from fully overcast) + =under the "simplified" PC2 initiation logic option (i_pc2_init_logic=2). + = + =Note that pc2_checks performs an independent additional check to remove + =liquid-cloud fractions below cloud_rounding_tol = 1.0E-12. +!kind=double +ns=namelist/Science/UM Cloud +range=1.0e-12:1.0e-1 +sort-key=Panel-A02b +type=real + +[namelist:cloud=cloud_pc2_tol_2] +compulsory=true +description=PC2 threshold liquid cloud fraction to retain cloud (RH > RHcrit) +fail-if=this > namelist:cloud=cloud_pc2_tol +help=When RH is above RHcrit, instances of liquid-cloud fraction below + =cloud_pc2_tol_2 are reset to zero at the end of each timestep. + =Also instances of liquid-cloud fraction above 1 - cloud_pc2_tol_2 + =are reset to 1. + =This threshold is also used in a couple other places: + = - Optical depth filtered cloud diagnostics are set to zero where + = the combined cloud fraction (stratiform + convective) + = is below the threshold. + = - The riming process in the Wilson Ballard microphysics scheme is only + = performed where the mixed-phase cloud-fraction exceeds the threshold. + = + =Note that pc2_checks performs an independent additional check to remove + =liquid-cloud fractions below cloud_rounding_tol = 1.0E-12. + = + =Also note that cloud_pc2_tol_2 should not exceed cloud_pc2_tol. +!kind=double +ns=namelist/Science/UM Cloud +range=1.0e-12:1.0e-1 +sort-key=Panel-A02b +type=real + +[namelist:cloud=dbsdtbs_turb_0] +compulsory=true +description=PC2 erosion rate parameter / s-1 +help=Controls the rate of turbulent dissipation of liquid-cloud in grid-mean + =subsaturated environments (and the rate of filling-in of sub-grid + =clear-sky fraction in grid-mean supersaturated environments). + =This process corresponds to narrowing the width of the sub-grid + =moisture distribution. The rate of turbulent dissipation of cloud liquid + =water-content is parameterised as: + = + = dqcl/dt = -K 2 Cl (1 - Cl) (qsat(T) - q) + = + =where q is the grid-mean vapour mixing-ratio, qsat(T) is the saturation + =vapour mixing-ratio w.r.t. liquid water at the grid-mean temperature, + =Cl is the liquid cloud-fraction, and K is the rate coefficient + =given by this namelist input. + =This formula makes the rate of cloud erosion scale with the + =subsaturation of the environment, and an estimate of the + =sub-grid area of exposed cloud edges. + =The rate of change of Cl is then calculated based on the width-narrowing + =rate which is consistent with the computed rate of evaporation of qcl. +!kind=double +ns=namelist/Science/UM Cloud +range=0.0:1.0e-2 +sort-key=Panel-A09b +type=real + +[namelist:cloud=ent_coef_bm] +compulsory=true +description=Bimodal cloud-scheme parcel method entrainment coefficient +help=In the bimodal cloud-scheme, when representing the skewness of the + =sub-grid saturation distribution using entraining parcels + =(i_bm_ez_opt='entpar'), this dimensionless coefficient scales the rate of + =dilution of the modes from above and below towards the current + =model-level values. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A10 +type=real + +[namelist:cloud=ez_max] +compulsory=true +description=Maximum entrainment zone depth for bimodal cloud scheme (m) +help=The bimodal cloud scheme (or bimodal initiation in PC2) searches for + = entrainment zones below sharp inversions. Ez_max sets a limit to how + = deep entrainment zones can become. The recommended value is 400m. +!kind=default +ns=namelist/Science/UM Cloud +range=300.0:500.0 +sort-key=Panel-A10 +type=real + +[namelist:cloud=falliceshear_method] +compulsory=true +description=Select how shear affects falling ice cloud fraction +!enumeration=true +help=Falling ice increases the ice cloud fraction in the layer it falls + = into. There is the option to include the effects of the further + = increase in the grid-box cloud fraction due to the lateral + = displacement as the ice falls because of the vertical shear of + = the horizontal wind. Either: + = a) the effects of shear can be ignored, + = b) a globally constant shear (not calculated from the actual wind) + = can be assumed or + = c) the effects of shear are considered and the shear is calculated + = from the model wind. + = + =When not using the globally constant value an additional ice cloud + = fraction source term is used to represent the lateral spreading out + = of ice cloud fraction while maintaining the same grid-box mean + = ice water content. +ns=namelist/Science/UM Cloud +sort-key=Panel-A04 +trigger=namelist:cloud=cff_spread_rate: 'off','real' +value-titles=Ignore the effects of shear, + =Assume a globally constant shear, + =Use shear derived from model winds +values='off','constant','real' + +[namelist:cloud=filter_optical_depth] +compulsory=true +description=Apply optical depth filter for cloud diagnostics. +help=If false: outputs the derived cloud diagnostics without any processing. + =If true: makes a simple estimate of the ice optical depth in each layer + = and ignores optically thin layers when calculating derived + = cloud diagnostics. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A11 +trigger=namelist:cloud=opt_depth_thresh: .true. +type=logical + +[namelist:cloud=fsd_conv_const] +compulsory=true +description=Inhomogeneity factor for convective cloud +help=Under some options for the representation of subgrid scale horizontal + = ice and liquid water content variability there is a + = different parameter scaling the variability under a convective + = cloud regime compared to a non-convective cloud one. Here the user + = can set that parameter for the convective regime. Originally in + = Hill et al (2015) this was set to 2.54 (their Eq 3) while GA7 to GA9 + = use the larger value of 2.81 (so more inhomogeneous) +!kind=default +ns=namelist/Science/UM Cloud +range=0.0: +sort-key=Panel-A07b +type=real + +[namelist:cloud=fsd_min_conv_frac] +compulsory=true +description=Minimum convective fraction in FSD parametrization +help=The minimum convective cloud fraction under which to consider a + = grid-box as convective when applying the Hill et al. (2015) + = fractional standard deviation parametrization +!kind=default +ns=namelist/Science/UM Cloud +range=0.0:1.0 +sort-key=Panel-A07a +type=real + +[namelist:cloud=fsd_nonconv_ice_const] +compulsory=true +description=Inhomogeneity factor for non-convective ice cloud +help=Under some options for the representation of subgrid scale horizontal + = ice and liquid water content variability there is a + = different parameter scaling the variability under a convective + = cloud regime compared to a non-convective cloud one. Here the user + = can set that parameter for the non-convective regime. Originally in + = Hill et al (2015) this was set to 0.96 (their Eq 3) while GA7 to GA9 + = use the larger value of 1.14 (so more inhomogeneous) +!kind=default +ns=namelist/Science/UM Cloud +range=0.0: +sort-key=Panel-A07d +type=real + +[namelist:cloud=fsd_nonconv_liq_const] +compulsory=true +description=Inhomogeneity factor for non-convective liquid cloud +help=Under some options for the representation of subgrid scale horizontal + = ice and liquid water content variability there is a + = different parameter scaling the variability under a convective + = cloud regime compared to a non-convective cloud one. Here the user + = can set that parameter for the non-convective regime. Originally in + = Hill et al (2015) this was set to 0.96 (their Eq 3) while GA7 to GA9 + = use the larger value of 1.14 (so more inhomogeneous) +!kind=default +ns=namelist/Science/UM Cloud +range=0.0: +sort-key=Panel-A07c +type=real + +[namelist:cloud=i_bm_ez_opt] +compulsory=true +description=Bimodal cloud scheme entrainment zone options +!enumeration=true +help=In the bimodal cloud-scheme + = (or bimodal-based initiation with PC2), + = There are several options for how to represent the skewness of + = the sub-grid saturation distribution at entrainment zones: + = (1) - Original method; each model-level is diagnosed to be either + = in an entrainment zone or not (based on the presence of a + = local maximum in dTl/dz). Model-levels inside an entrainment + = zone have skewness represented by a combination of modes drawn + = from discreet model-levels at the base and top of that zone. + = Model-levels not diagnosed to be in an entrainment zone + = have a symmetrical distribution / no skewness. + = (2) - Subcritical-only method; as (1), but the diagnosis of an + = entrainment zone additionally requires that the zone overlaps + = with a turbulent layer (either Ri < 1, or below the top height + = of non-local boundary-layer mixing). + = (3) - Entraining parcel method; all model-levels are allowed to have + = skewness, represented by drawing modes from above and below + = based on the properties of entraining parcels subsided from + = above / ascended from below. The entrainment rate scales with + = 1 / the turbulent length-scale Km/sqrt(w_var), + = so that the parcels tend to the current environment values if + = the turbulent length-scale is small + = (so that skewness becomes negigible in this limit). +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A10 +trigger=namelist:cloud=ent_coef_bm: 'entpar'; +value-titles=Original method, + =Subcritical-only method, + =Entraining parcel method +values='orig','subcrit','entpar' + +[namelist:cloud=i_pc2_erosion_numerics] +compulsory=true +description=Numerical method for time integration of PC2 cloud erosion +!enumeration=true +help=The PC2 erosion term is often "fast" relative to the timestep length, + =which causes problems with numerical overshoot; e.g. when convection + =detrains cloud into a dry environment, the erosion rate is often + =high enough to remove all the detrained cloud within the timestep. + = + =With the explicit numerical method, + =this is addressed by not allowing erosion to act on + =the current timestep convective cloud increment, so that some + =detrained cloud survives to the end of the timestep. + =However, that method yields an end-of-timestep cloud amount which + =scales with the timestep length, which is problematic. + = + =With the implicit numerical method, erosion is allowed + =to act on the fully updated cloud fields after convection, + =but is solved such that the erosion rate applied is approximately + =consistent with the cloud-fraction that will occur after the + =erosion increment has been added on. + =This avoids the numerical overshoot, while reducing timestep sensitivity. + = + =One problem with the implicit method is that it makes it impossible for + =erosion to completely remove cloud. This makes it easy for numerical + =diffusion in the model to spread small cloud amounts far and wide, + =even into grid-points with low RH where there shouldnt be any cloud. + = + =A 3rd option computes an approximate analytical solution to the equations + =posed for the erosion, such that the rate of removal of qcl does decline + =realistically as cfl approaches zero, but the cloud can eventually + =be eroded away completely. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A09b +value-titles=Explicit forwards-in-time, + =Implicit w.r.t. cloud-fraction, + =Analytical solution +values='explicit','implicit','analytic' + +[namelist:cloud=ice_width] +compulsory=true +description=Width of vapour distribution in liquid-free part of gridbox +help=Ice width specifies the ice content (in terms of a fraction of + = qsat_liq) that corresponds to a factor of two reduction in the + = width of the vapour distribution in the liquid-free part of the + = gridbox. This is only available if a subgrid partitioning of + = out-of-liquid-cloud water vapor is requested (subgrid_qv=true). +!kind=default +ns=namelist/Science/UM Cloud +range=0.0:1.0 +sort-key=Panel-A05a +type=real + +[namelist:cloud=l_bm_sigma_s_grad] +compulsory=true +description=Account for local gradients in sub-grid saturation variance +help=In the bimodal cloud-scheme + = (or bimodal-based initiation with PC2), + = correct the saturation variance sigma_S given to each mode of the + = sub-grid moisture PDF, to account for the local vertical gradient + = in grid-mean saturation. Also corrects the calculation of + = dqsat/dz following a parcel to account for the change in pressure. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A10 +type=logical + +[namelist:cloud=l_bm_tweaks] +compulsory=true +description=Make several miscellaneous minor tweaks to the bimodal cloud-scheme +help=In the bimodal cloud-scheme + = (or bimodal-based initiation with PC2), + = this switch activates the following minor changes: + = a) Impose a minimum limit on the turbulent moisture variance, + = consistent with the limit already imposed when determining + = where condensation should occur. + = b) Truncate the Gaussian distributions at max_sigmas standard deviations, + = consistent with the logic determining where condensation should occur. + = c) Add extra checks to prevent the scheme from predicting negative qcl + = where q is negative. + = d) Also avoid negative qcl resulting from floating point rounding error + = in a calculation of mixed-phase fraction. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A10 +type=logical + +[namelist:cloud=max_sigmas] +compulsory=true +description=Max width of bimodal cloud-scheme Gaussian PDFs +help=The bimodal cloud-scheme assumes the local turbulent moisture + =fluctuations follow Gaussian PDFs. Strictly speaking, Gaussians + =never quite fall to zero, so technically assuming Gaussian dsitributions + =can never yield zero cloud-amount. To avoid getting silly tiny + =cloud-fractions everywhere, the Gaussians are truncated at a certain + =number of standard deviations from their means. This namelist + =input sets that number. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A10 +type=real + +[namelist:cloud=min_sigx_ft] +compulsory=true +description=Bimodal cloud-scheme minimum free troposphere moisture variability +help=The bimodal cloud-scheme diagnoses the standard deviation of sub-grid + =moisture variability based on boundary-layer scheme turbulence fields. + =However, often the free troposphere can contain large moisture variability + =in non-turbulent conditions (e.g. leftover from earlier convection). + =This namelist input sets an imposed minimum standard deviation of the + =unimodal moisture PDFs (in units of RH), applied only in the free + =troposphere, to account for missed non-turbulent moisture variability. + =Note that an equivalent "RHcrit" (threshold RH for cloud formation) + =is given by 1 - min_sigx_ft * max_sigmas. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A10 +type=real + +[namelist:cloud=mphys_erosion] +compulsory=true +description=Include PC2 erosion as a microphysical term +help=If true: PC2 erosion is included with the microphysics code + =If false: PC2 erosion is included with the convection code +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A09 +type=logical + +[namelist:cloud=opt_depth_thresh] +compulsory=true +description=Cloud diagnostics optical depth threshold. +help=Amount of ice optical depth below which cloud cover in + = that layer is ignored when using filter_optical_depth. +!kind=default +ns=namelist/Science/UM Cloud +range=0.0:10.0 +sort-key=Panel-A11a +type=real + +[namelist:cloud=pc2_init_logic] +compulsory=true +description=Options for where to allow PC2 initiation to operate +!enumeration=true +help=(1) Original logic; + = Tests are performed to check whether the cloud cover is 0 or 1 + = (but if it is below zero degree C we check for cloud cover less + = than 0.05 or greater than 1). + = Tests on being above the LCL when considering initiating away from 0 are + = also done early on, confusing the logic somewhat. + = Also the logic prevents PC2 initiating cloud above a convective + = boundary layer (because of assumption that there is a convection + = scheme in use that will detrain cloud and create cloud that way instead). + = This is an issue in a convection-permitting model where there is no + = convection scheme to create that cloud via detrainment. + = + =(3) Much simpler logic that should yield smoother behaviour; + = The diagnostic cloud scheme calculations (Smith or Bimodal) + = are performed at any grid-point where they are expected to yield + = nonzero liquid water content, regardless of the existing cloud fraction. + = The diagnosed qcl is then taken as a minimum limit applied + = to the PC2 prognostic qcl. Cloud fraction is adjusted towards the + = diagnostic scheme value in proportion to the fractional increase + = of qcl by initiation (or the fractional increase of saturation deficit + = at points which are grid-mean total-water supersaturated). +ns=namelist/Science/UM Cloud +sort-key=Panel-A02b +value-titles=Original,Smooth +values='original','smooth' + +[namelist:cloud=pc2ini] +compulsory=true +description=Method for doing PC2 initiation +!enumeration=true +help=Smith-like initiation as described in Wilson et al (2008). When cloud + = fraction is 0 or 1, cloud will be generated or removed based on a + = triangular subgrid PDF with a width based on the RHcrit profile. + = + =Bimodal scheme: call the bimodal cloud scheme when cloud fraction is 0 + = or 1 to determine whether cloud should be initiated or removed based + = on a bimodal Gaussian subgrid PDF with variances determined from the + = turbulent properties as in Furtado et al. (2016). +ns=namelist/Science/UM Cloud +sort-key=Panel-A02a +value-titles=Smith,Bimodal +values='smith','bimodal' + +[namelist:cloud=rh_crit] +!bounds=namelist:extrusion=number_of_layers +compulsory=true +description=Critical relative humidity +fail-if=len(this) != namelist:extrusion=number_of_layers ; +help=The critical relative humidity is used in the cloud scheme to define + = the ratio at which cloud starts to form. Values may vary depending on + = the configuration. Please refer to standard jobs for current + = recommended settings. + = + = The number of values must match the number of levels in the model. + = +!kind=default +length=: +ns=namelist/Science/UM Cloud +range=0.0:1.0 +sort-key=Panel-A03 +type=real + +[namelist:cloud=rh_crit_opt] +compulsory=true +description=RHCrit parametrization method +!enumeration=true +help=If no parametrization is selected, + =the values in the table below + = are used. + = + =The boundary layer TKE based method predicts the sub-grid + = variability based on the gradients, + =eddy diffusivities and + = TKE predicted by the boundary layer scheme. It does still + = make use of the table values in the microphysics code for + = parametrizing the RH of the clear sky portion of the grid-box. +ns=namelist/Science/UM Cloud +sort-key=Panel-A02 +value-titles=No parametrization, + =Boundary layer TKE based method +values='namelist','tke' + +[namelist:cloud=scheme] +compulsory=true +description=Cloud scheme +!enumeration=true +help=Choice of UM cloud scheme to use + = + = Smith scheme (1990): + = Uses the diagnostic cloud fraction and condensate variables, + = based on a symmetric triangualar PDF of subgrid variability. + = + = Bimodal scheme (Van Weverberg et al 2021) + = Uses the diagnostic cloud fraction and condensate variables, + = based on a bimodal PDF of sugrid variability. + = + = PC2 scheme (Wilson et al 2008): + = Uses the prognostic cloud and prognostic condensate scheme. + = + = Note: Disabling the cloud scheme will result in no updates to + = the cloud fraction or water content from the cloud scheme. + = Micro-physics updates to cloud are unaffected by this + = setting. + = +ns=namelist/Science/UM Cloud +sort-key=Panel-A01 +trigger=namelist:cloud=mphys_erosion: 'pc2' ; + =namelist:cloud=i_pc2_erosion_numerics: 'pc2' ; + =namelist:cloud=dbsdtbs_turb_0: 'pc2' ; + =namelist:cloud=ez_max: 'pc2', 'bimodal' ; + =namelist:cloud=i_bm_ez_opt: 'pc2', 'bimodal' ; + =namelist:cloud=l_bm_sigma_s_grad: 'pc2', 'bimodal' ; + =namelist:cloud=l_bm_tweaks: 'pc2', 'bimodal' ; + =namelist:cloud=max_sigmas: 'pc2', 'bimodal' ; + =namelist:cloud=min_sigx_ft: 'pc2', 'bimodal' ; + =namelist:cloud=turb_var_fac_bm: 'pc2', 'bimodal' ; + =namelist:external_forcing=pc2_force_response: 'pc2'; +value-titles=Smith, PC2, Bimodal +values='smith', 'pc2', 'bimodal' + +[namelist:cloud=subgrid_qv] +compulsory=true +description=Calculate a partitioning of water vapor outside of liquid cloud +help=Setting this option to true partitions the out-of-liquid-cloud water vapor + =in each gridbox between clear-sky and sublimating and depositing ice-cloud + =regions. If this is turned off then qv is the same throughout the + =clear-sky and ice-cloud parts of each gridbox. Which means that the ice + =is either entirely sublimating of entirely growing, + =depending on the value of + =the in-ice-cloud relative humidity. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A05 +trigger=namelist:cloud=ice_width: .true. +type=logical + +[namelist:cloud=turb_var_fac_bm] +compulsory=true +description=Bimodal cloud-scheme unimodal variance coefficient +help=In the bimodal cloud-scheme, this dimensionless coefficient + =scales the widths of the local turbulent sub-grid saturation PDFs. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A10 +type=real + +[namelist:cloud=two_d_fsd_factor] +compulsory=true +description=Factor to convert 1D FSD for straight line to 2D value +help=Current parametrizations of FSD (fractional standard deviation, + =a measure + =of subgrid variability) of cloud water content used in radiation and + =microphysics schemes are based on observations taken in a 1D line. For the + =UM we require the FSD for a 2D gridbox, + =which is generally larger. We + =account for this difference by multiplying the 1D fsd by this value. +!kind=default +range=1:2 +sort-key=Panel-A08b +type=real + +[namelist:cloud=use_fsd_eff_res] +compulsory=true +description=Whether to use a hardwired effective resolution in fractional standard deviation (FSD) scheme +help=If true: use the FSD equations (from Boutle et al (2014) or Hill et al (2015)) + = with a fixed grid-size representative of N96/C48. + =If false: use the FSD equations (from Boutle et al (2014) or Hill et al (2015)) + = with an estimate of the grid-size calculated from the grid. +!kind=default +ns=namelist/Science/UM Cloud +sort-key=Panel-A08a +type=logical diff --git a/interfaces/physics_schemes_interface/rose-meta/um-convection/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-convection/version30_31.py new file mode 100644 index 000000000..ebefea03d --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-convection/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-convection/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-convection/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-convection/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-convection/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-convection/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-convection/vn3.1/rose-meta.conf new file mode 100644 index 000000000..b63b84efe --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-convection/vn3.1/rose-meta.conf @@ -0,0 +1,170 @@ +#============================================================================== +# CONVECTION: +#============================================================================== + +[namelist:convection] +compulsory=true +description=Convection parametrization +ns=namelist/Science/UM Convection +sort-key=Section-A06 +title=Convection + +[namelist:convection=cape_timescale] +compulsory=true +description=Timescale in seconds for CAPE closure scheme +help=This determines the e-folding time for the dissipation of CAPE. + = There is some observational evidence for a timescale of the order of + = an hour. The convection scheme seems to work better with a shorter CAPE + = timescale of around half an hour (1800 secs). +!kind=default +range=1:9999999 +sort-key=Panel-03 +type=real + +[namelist:convection=cv_scheme] +compulsory=true +description=Convection scheme +!enumeration=true +help=Convection scheme to use, options are: + =GregoryRowntree - UM 6A mass flux scheme + =LambertLewis - UM other convection scheme 10 + =Comorph - ComorphA scheme +sort-key=Panel-01 +trigger=namelist:convection=number_of_convection_substeps: 'gregory_rowntree'; + =namelist:convection=cape_timescale: 'gregory_rowntree'; + =namelist:convection=efrac: 'gregory_rowntree'; + =namelist:convection=prog_ent_min: 'gregory_rowntree'; + =namelist:convection=orig_mdet_fac: 'gregory_rowntree'; + =namelist:convection=par_gen_mass_fac: 'comorph'; + =namelist:convection=par_gen_rhpert: 'comorph'; + =namelist:convection=par_radius_ppn_max: 'comorph'; +value-titles=GregoryRowntree, LambertLewis, Comorph +values='gregory_rowntree','lambert_lewis','comorph' + +[namelist:convection=dx_ref] +compulsory=true +description=Reference grid-length for Comorph A resolution-dependence / m +help=When using the resolution-dependent link between parcel radius + =and precipitation rate, dx_ref is the grid-length at which the + =namelist input value of par_radius_ppn_max applies. + =Typically set to 50000.0m (ie. 50km). +!kind=default +range=100.0:1000000.0 +sort-key=Panel-08 +type=real + +[namelist:convection=efrac] +compulsory=true +description=Evaporative fraction of fluxes at mid-level cloud base +help=This defines the ratio of latent heat flux to sensible plus latent + = heat flux at mid-level cloud base due to the initial perturbation. + = Only used if md_pert_opt=1 or 2. If md_pert_opt=2 then efrac just + = sets the cloud base evaporative fracton away from the boundary + = layer. +!kind=default +range=-10.0:10.0 +sort-key=Panel-03b +type=real + +[namelist:convection=l_cvdiag_ctop_qmax] +compulsory=true +description=Revised check for well-mixed q-profile in convective diagnosis. +help=In the convective diagnosis "cumulus test", use a revised + =check for a well-mixed q-profile. By default, grid-columns where + =the mean vertical q-gradient between cloud-base and the parcel-top is + =small are not allowed to diagnose cumulus. But if this switch is on, + =they are allowed if the gradient between cloud-base and any local + =minimum q found below the parcel-top is larger. This accounts for + =occasions when the profile is not well-mixed, but contains a local + =maximum q at cloud-top (due to strong detrainment there), with drier + =air beneath. +!kind=default +sort-key=Panel-01 +type=logical + +[namelist:convection=number_of_convection_substeps] +compulsory=true +description=Number of convection substeps per model time step +help=Normal set to 2 for Gregory Rowntree scheme when used in the UM. + =Ideally we would prefer this as 1 + =Has been set higher than 2 by users trying to avoid UM instabilities + =in the past. Not recommended as a solution to model instabilities. +!kind=default +range=1:5 +sort-key=Panel-02 +type=integer + +[namelist:convection=orig_mdet_fac] +compulsory=true +description=Factor multiplying the original mixing detrainment rate. +help=Factor multiplying the original mixing detrainment rate. + =Original default 1.0 +!kind=default +range=0.0:5.0 +sort-key=Panel-03d +type=real + +[namelist:convection=par_gen_mass_fac] +compulsory=true +description=Coefficient scaling the initiating mass sources (dimensionless) +help=Higher values could mean that the layer-cloud in unstable environments + =convects away more rapidly, leading to reduced layer-cloud in such + =environments. + =Recommended value 0.25 +!kind=default +range=0.01:1.0 +sort-key=Panel-04 +type=real + +[namelist:convection=par_gen_rhpert] +compulsory=true +description=Comorph neutrally-buoyant parcel initial RH perturbation (fractional) +help=Sets the magnitude of the "background" parcel initial moisture excess + = in Relative Humidity (decimal fraction). +!kind=default +sort-key=Panel-05 +type=real + +[namelist:convection=par_radius_ppn_max] +compulsory=true +description=Comorph precip rate at which max parcel radius scaling occurs. +help=Scales the parcel initial radius, which determines the entrainment rate. +!kind=default +sort-key=Panel-06 +type=real + +[namelist:convection=prog_ent_min] +compulsory=true +description=Minimum scaling when calculating entrainment from prognostic field +help=Minimum scaling applied when calculating entrainment scaling from + = 3d prognostic field based on surface precipitation. + = 6a scheme only. Used under ent_opt_md,ent_opt_dp=6 or 7 and needs + = l_conv_prog_precip=T. +!kind=default +range=0.0:5.0 +sort-key=Panel-03c +type=real + +[namelist:convection=qlmin] +compulsory=true +description=Minimum critical cloud condensate +help=Minimum Critical Cloud Condensate + = + = This sets the minimum value of the critical cloud condensate profile. + = This is related to the option settings for ccw_for_precip_opt. + = This will always be applied for option 4 but will only be applied to + = options 0-3 if PC2 is switched on. +!kind=default +range=0:1e-3 +sort-key=Panel-03a +type=real + +[namelist:convection=resdep_precipramp] +compulsory=true +description=Include grid-length dependence in Comorph A parcel radius precip ramp +help=Option to make the CoMorph A parcel radius dependence on the + =precipitation rate a function of the grid size, and so allow for + =the ability to resolve higher precip rates at higher resolution. +!kind=default +sort-key=Panel-07 +type=logical diff --git a/interfaces/physics_schemes_interface/rose-meta/um-iau/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-iau/version30_31.py new file mode 100644 index 000000000..0318d8a76 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-iau/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-iau/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-iau/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-iau/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-iau/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-iau/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-iau/vn3.1/rose-meta.conf new file mode 100644 index 000000000..b124f233f --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-iau/vn3.1/rose-meta.conf @@ -0,0 +1,161 @@ +#============================================================================== +# IAU +#============================================================================== + +[namelist:iau] +compulsory=true +description=Setup the IAU option cases +help=This namelist is for the options related to the + = Incremental Analysis Update (IAU) +ns=namelist/Science/IAU +sort-key=Z + +[namelist:iau=iau_ainc_multifile] +compulsory=true +description=Enable 4D-IAU +help=This enables application of different sets of analysis + = increments over different parts of the IAU time window, + = known as 4D-IAU +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +trigger=namelist:iau_ainc_io=filename: .true.; + =namelist:iau_ainc_io=start_time: .true.; +type=logical + +[namelist:iau=iau_mode] +compulsory=true +description=whether IAU needs to act instantaneously or over window +!enumeration=true +!kind=default +sort-key=Panel-A07 +trigger=namelist:iau=iau_ts_start: 'time_window','time_mixed'; + =namelist:iau=iau_use_pertinc: 'time_window','time_mixed'; + =namelist:iau=iau_window_length: 'time_window','time_mixed'; +values='instantaneous', 'time_window', 'time_mixed' + +[namelist:iau=iau_pc2] +compulsory=true +description=Enable PC2 assimilation in IAU +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +type=logical + +[namelist:iau=iau_tendency_addinf] +compulsory=true +description=Enable additive inflation as tendencies +help=This enables additive inflation increments in the form + = of tendencies (units: quantity per second, e.g.Ks^-1) as + = opposed to standard increments (units: quantity, e.g.K) +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +type=logical + +[namelist:iau=iau_tendency_ainc] +compulsory=true +description=Enable analysis increments as tendencies +help=This enables analysis increments in the form + = of tendencies (units: quantity per second, e.g.Ks^-1) as + = opposed to standard increments (units: quantity, e.g.K) +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +type=logical + +[namelist:iau=iau_tendency_bcorr] +compulsory=true +description=Enable bias correction as tendencies +help=This enables bias correction increments in the form + = of tendencies (units: quantity per second, e.g.Ks^-1) as + = opposed to standard increments (units: quantity, e.g.K) +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +type=logical + +[namelist:iau=iau_tendency_pertinc] +compulsory=true +description=Enable perturbation increments as tendencies +help=This enables perturbation increments in the form + = of tendencies (units: quantity per second, e.g.Ks^-1) as + = opposed to standard increments (units: quantity, e.g.K) +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +type=logical + +[namelist:iau=iau_ts_start] +compulsory=true +description=Timestep that IAU should start +fail-if=this < 1 ; +!kind=default +sort-key=Panel-A07 +type=integer + +[namelist:iau=iau_use_addinf] +compulsory=true +description=Enable use of additive inflation in IAU +help=If enabled, additive inflation from the ensemble DA is added to the + = model prognostic state throughout the model run +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +trigger=namelist:files=iau_addinf_path: .true.; + =namelist:iau=iau_tendency_addinf: .true.; + =namelist:iau_addinf_io=filename: .true.; + =namelist:iau_addinf_io=start_time: .true.; +type=logical + +[namelist:iau=iau_use_bcorr] +compulsory=true +description=Enable use of bias correction in IAU +help=If enabled, bias correction from the ensemble DA is added to the + = model prognostic state throughout the model run +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +trigger=namelist:files=iau_bcorr_path: .true.; + =namelist:iau=iau_tendency_bcorr: .true.; + =namelist:iau_bcorr_io=filename: .true.; + =namelist:iau_bcorr_io=start_time: .true.; +type=logical + +[namelist:iau=iau_use_level_one_temp] +compulsory=true +description=Enable use of level1 temperature increments to update + = surface temperatures +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +type=logical + +[namelist:iau=iau_use_pertinc] +compulsory=true +description=Enable use of perturbation increments in IAU +help=If enabled, analysis increments from the perturbation members of + = the control-pert ensemble DA are added to the model prognostic + = state throughout the IAU time window +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +trigger=namelist:files=iau_pert_path: .true.; + =namelist:iau=iau_tendency_pertinc: .true.; +type=logical + +[namelist:iau=iau_wet_density] +compulsory=true +description=Enable density increments in form of wet density*r^2 +!kind=default +ns=namelist/Science/IAU +sort-key=Panel-A07 +type=logical + +[namelist:iau=iau_window_length] +compulsory=true +description=Length of time in seconds IAU needs to act over +fail-if=this < 0 ; +!kind=default +sort-key=Panel-A07 +type=integer diff --git a/interfaces/physics_schemes_interface/rose-meta/um-microphysics/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-microphysics/version30_31.py new file mode 100644 index 000000000..b74300787 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-microphysics/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-microphysics/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-microphysics/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-microphysics/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-microphysics/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-microphysics/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-microphysics/vn3.1/rose-meta.conf new file mode 100644 index 000000000..0c542ee37 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-microphysics/vn3.1/rose-meta.conf @@ -0,0 +1,484 @@ +#============================================================================== +# MICROPHYSICS +#============================================================================== + +[namelist:microphysics] +compulsory=true +description=Microphysics parametrizations +ns=namelist/Science/UM Microphysics +sort-key=Section-A08 +title=Microphysics + +[namelist:microphysics=a_ratio_exp] +compulsory=true +description=Exponent in the cross-sectional area ratio relation ice +help=When the shape-dependent riming rates are used, + =this is the exponent + =used to specify the cross-sectional area of ice particles. + =The cross-sectional area ratio is given as + =R(D) = a_ratio_input D^a_ratio_exp. In the code, + =the + =actual particle area is A = R*D^2 (the neglected factor of 4/pi + =being considered as part uncertainity in + =the collection efficency of ice/liquid collisions). +!kind=default +ns=namelist/Science/UM Microphysics +range=-1:0 +sort-key=Panel-A01a +type=real + +[namelist:microphysics=a_ratio_fac] +compulsory=true +description=Prefactor in the cross-sectional area ratio relation ice +help=When the shape-dependent riming rates are used, + =this is the prefactor + =used to specify the cross-sectional area of ice particles. + =The cross-sectional area ratio is given as + =R(D) = a_ratio_input D^a_ratio_exp. In the code, + =the + =actual particle area is A = R*D^2 (the neglected factor of 4/pi + =being considered as part of the uncertainity in + =the collection efficency of ice/liquid collisions). +!kind=default +ns=namelist/Science/UM Microphysics +range=0:1 +sort-key=Panel-A01b +type=real + +[namelist:microphysics=c_r_correl] +compulsory=true +description=Cloud-rain correlation coefficient +help=Cloud-rain correlation coefficient for use with inhomogeneity + =parametrization in improved warm rain microphysics scheme. +!kind=default +ns=namelist/Science/UM Microphysics +range=-1:1 +sort-key=Panel-A05 +type=real + +[namelist:microphysics=casim_cdnc_opt] +compulsory=true +description=How to calculate cloud number in Casim +!enumeration=true +help=External will take the cloud number calculated by an external aerosol + = scheme for use in CASIM, e.g. UKCA activate or Glomap climatologies + = with the Jones relation + = + =Fixed number will use a fixed cloud drop number, as in RA3 +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A02 +value-titles=External code, Fixed number +values='external','fixed' + +[namelist:microphysics=ci_input] +compulsory=true +description=Prefactor in fallspeed relation of large ice +help=When two different ice fall speeds are used, + =this is the prefactor + =used to specify the fallspeed of the large ice particles. + =The fall speed is given as v(D) = ci_input D^di_input +!kind=default +ns=namelist/Science/UM Microphysics +range=0:1e7 +sort-key=Panel-A01b +type=real + +[namelist:microphysics=cic_input] +compulsory=true +description=Prefactor in fallspeed relation of small ice +help=When two different ice fall speeds are used, + =this is the + =prefactor used to specify the fallspeed of the small ice. + =The fall speed is given as v(D) = cic_input D^dic_input +!kind=default +ns=namelist/Science/UM Microphysics +range=0:1e7 +sort-key=Panel-A01b +type=real + +[namelist:microphysics=droplet_tpr] +compulsory=true +description=Enable tapering of cloud droplets towards surface +help=This scheme allows droplet numbers to be tapered from their maximum + =value down to a lower value towards the surface, + =and improves + =microphysical representation during low cloud and fog events. + = + =To activate this scheme, + =activate namelist:microphysics=droplet_tpr + =z_peak_nd=150.0 m is hard-wired in UM code as height below which to + =taper the droplet numbers (150m is chosen) + =Select a value of the droplet number concentration at + =namelist:microphysics=ndrop_surf - 50.0E6 to 75.0E6 is recommended + =20.0E6 to 100.0E6 is typical of fog measurements at Cardington MRU. + =For further information, see Wilkinson et al (2013), QJRMS + =http://dx.doi.org/10.1002/qj.1975 +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A02 +trigger=namelist:microphysics=ndrop_surf: .true.; + =namelist:microphysics=z_surf: .true.; + =namelist:stochastic_physics=rp_mp_ndrop_surf: .true.; +type=logical + +[namelist:microphysics=fcrit] +compulsory=true +description=Critical Froude number below which flow blocking occurs +help=Needed by the seeder feeder scheme when blocking is switched on. + =The amount of low-level blocking due to sub-grid orography is determined + =by the Froude number F (U/NH). When F falls below Fcrit, blocking occurs. + =The blocked layer depth zb increases linearly from zero to the full + =sub-grid hill peak-to-trough height as F decreases from Fcrit towards zero. + =The most physically realistic value of fcrit is around 1. + =Using a larger value increases the amount of blocking and therefore + =decreases the amount of ascent, resulting in less precipitation enhancement. + =Value must be greater than zero. +!kind=default +ns=namelist/Science/UM Microphysics +range=0.1: +sort-key=Panel-A04f +type=real + +[namelist:microphysics=graupel_scheme] +compulsory=true +description=Option for inclusion of graupel +!enumeration=true +help=Options for the inclusion of a prognostic graupel category in the + =UM microphysics code. + = + = - No prognostic graupel in use. + = + = - Modified scheme with snow-rain collisions producing graupel, + = according to the following table: + = ---------------------------------------------------------------- + = ICE TYPE | RAIN MIXING RATIO | COLLISION RESULTS IN + = CRYSTALS | > 1.0E-4 KG/KG | CRYSTALS + = CRYSTALS | < 1.0E-4 KG/KG | CRYSTALS + = SNOW AGGREGATES | > 1.0E-4 KG/KG | GRAUPEL + = SNOW AGGREGATES | < 1.0E-4 KG/KG | SNOW AGGREGATES + = ---------------------------------------------------------------- + = When the generic ice PSD is switched on, the mean diameter of the + = particles is used to determine whether the collision results in ice + = aggregates or graupel. If the mean diameter of water is larger, then + = graupel particles will be formed. Otherwise the result of the collision + = will be an increase in the mixing ratio of aggregates. + = + = If this option is not selected, then a collision between rain and + = crystals produces crystals and similarly, a collision between rain and + = aggregates forms aggregates. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A04 +value-titles=No graupel,Modified scheme +values='none','modified' + +[namelist:microphysics=heavy_rain_evap_fac] +compulsory=true +description=Factor for enhancing evaporation at high rain rates +help=This scales an additional term in the rain evaporation rate formula, + =proportional to the rain mixing-ratio, qrain. The other terms are + =proportional to qrain raised to much lower powers; hence those terms + =dominate when qrain is small. As a result this new factor can be + =thought of as representing the break up of large drops, at large qrain, + =that leads to an increase in rain number at the expense of particle size, + =in turn making the evaporation rate scale more linearly with qrain. + =The net result is to modify the calculation in such a way that it makes + =no difference to light rain, but gradually ramps up the evaporation rate + =for very heavy rain. A value of 2.5e7 is recommended. +!kind=default +ns=namelist/Science/UM Microphysics +range=0.0:1.0e9 +sort-key=Panel-A05a +type=real + +[namelist:microphysics=i_update_precfrac] +compulsory=true +description=Options for how to update the prognostic precip fraction +!enumeration=true +help=If the prognostic precip fraction is used (l_mcr_precfrac=.true.), + =When any microphysics process increments the prognostic mass of + =rain and/or graupel, it needs to increment the precip fraction + =consistently. The options for how to do this are: + =(1) - Calculate an updated effective fraction based on the increments + = to precip mass squared within assumed homogeneous sub-grid areas. + =(2) - Calculate the increments to grid-mean precip mass squared based on + = assumed correlations between the existing mass and the increments. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A01f +value-titles=Assumed homogenous sub-grid areas, + =Assumed sub-grid spatial correlations +values='homog','correl' + +[namelist:microphysics=l_mcr_precfrac] +compulsory=true +description=Include prognostic rain/graupel fraction +help=Switch to include a prognostic field for the fraction of the + =grid-box occupied by falling rain and/or graupel. + = + =If used, the calculation of the rain fraction in the microphysics + =scheme is modified to take account of the previous timestep value. + =When a process adds additional rain/graupel, the new fraction is + =weighted towards the cloud fraction within-which the new rain/graupel + =is generated, as a function of the precip mass added. + =This avoids a problem where the rain fraction can only increase + =with time unless the rain disappears completely. + = + =Graupel is also included in this prognostic sub-grid fraction + =if prognostic graupel is turned on. + = + =Note: you must use prognostic fields for rain or graupel mass + =in order to use the prognostic precipation fraction. + = + =Prognostic precip fraction is not yet available with the CASIM + =microphysics scheme; it has only been implemented in the Wilson-Ballard + =scheme code. +ns=namelist/Science/UM Microphysics +sort-key=Panel-A01e +trigger=namelist:microphysics=i_update_precfrac: .true. ; +type=logical + +[namelist:microphysics=l_proc_fluxes] +compulsory=true +description=Apply microphysics process rates to the fall-fluxes. +help=If false, the fall-flux of each hydrometeor species cannot be + = modified by the microphysical processes (once it has been calculated + = by the sedimentation call). This leads to numerical problems. + = For example, if rain is falling, and the model-levels are shallow, then + = only a small fraction of the fall-flux will remain on a given + = model-level, with most of it falling straight through. The small + = amount of qrain left on the current level after sedimentation + = may fully evaporate, but most of the rain can spuriously fall through + = without being subject to evaporation. This leads to spurious small + = rain-rates reaching the surface in dry environments, where all the + = rain should have evaporated before reaching the surface. + = + = With this switch set to true, this problem is fixed by allowing + = microphysical processes to act on the fall-out flux of each + = species as well as the mass left on the current level. + = + =This option is not yet available with the CASIM + =microphysics scheme; it has only been implemented in the Wilson-Ballard + =scheme code. +ns=namelist/Science/UM Microphysics +sort-key=Panel-A01d +type=logical + +[namelist:microphysics=microphysics_casim] +compulsory=true +description=Run with CASIM scheme +help=Setting to True will switch from the Wilson and Ballard (1999) + =microphysics scheme to the Cloud-AeroSol Interacting Microphysics + =(CASIM). This is a multi-moment microphysics scheme which is + =significantly more advanced and can include complex cloud-aerosol + =interactions. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A00 +trigger=namelist:microphysics=casim_cdnc_opt: .true.; + =namelist:microphysics=graupel_scheme: .false.; + =namelist:microphysics=shape_rime: .false.; + =namelist:microphysics=orog_rain: .false.; + =namelist:microphysics=prog_tnuc: .false.; + =namelist:microphysics=c_r_correl: .false.; + =namelist:microphysics=l_mcr_precfrac: .false.; + =namelist:microphysics=l_proc_fluxes: .false.; +type=logical + +[namelist:microphysics=mp_dz_scal] +compulsory=true +description=Layer thickness scaling factor +help=This number is a scaling factor applied to the layer thickness + = which determines the vertical length scale over which the + = turbulence is assumed to mix. Increasing it will increase the + = production of liquid water cloud by turbulence. +!kind=default +ns=namelist/Science/UM Microphysics +range=0.01:10.0 +sort-key=Panel-A03b +type=real + +[namelist:microphysics=ndrop_surf] +compulsory=true +description=Surface droplet number concentration when tapering +help=This scheme allows droplet numbers to be tapered from their maximum + =value down to a lower value towards the surface, + =and improves + =microphysical representation during low cloud and fog events. + = + =To activate this scheme, + =activate namelist:microphysics=droplet_tpr + =z_peak_nd=150.0 m is hard-wired in UM code as height below which to + =taper the droplet numbers (150m is chosen) + =Select a value of the droplet number concentration at + =namelist:microphysics=ndrop_surf - 50.0E6 to 75.0E6 are typical + =20.0E6 to 100.0E6 was suggested by fog measurements at Cardington MRU. +!kind=default +ns=namelist/Science/UM Microphysics +range=1e6:375e6 +sort-key=Panel-A02a +type=real + +[namelist:microphysics=nscalesf] +compulsory=true +description=Scaling factor controlling the vertical decay of Seeder Feeder effect +help=The factor used to scale the horizontal wavelength of the assumed + =sinusoidal ridge in the Seeder Feeder scheme. + =This is only used to determine the vertical decay rate in the sub-grid + =orographic vertical displacements (does not determine near-surface values). + =At any given altitude z, the maximum vertical sub-grid orographic streamline + =displacement is the effective amplitude of the assumed sinusoidal hill + =multiplied by exp(-z k / nscalesf), where k is the orography wavenumber. + =A value of 1 assumes that the sub-grid orographic wavelength is equal to + =the horizontal model grid spacing. + =Larger values increase the assumed scale and reduce the vertical decay rate, + =so that orographic precipitation enhancement will increase at higher levels + =if the RH is large enough. + =It is not recommended to go above a value of 6 as those wavelengths + =are almost completely present in the resolved orography. +!kind=default +ns=namelist/Science/UM Microphysics +range=0.01:6.0 +sort-key=Panel-A04c +type=real + +[namelist:microphysics=nsigmasf] +compulsory=true +description=Orographic standard deviation scaling factor +help=The factor used to scale the sub-grid orographic standard deviation + =to estimate the peak-to-trough amplitude of the assumed sinusoidal ridge. + =Physically this might be approx 2.828427, so that the standard deviation + =for the assumed sinusoidal ridge is the same as the value for the + =actual subgrid orography. + =Larger values increase the hill peak amplitude and therefore the amount + =of precipitation enhancement produced (unless blocking is increased). +!kind=default +ns=namelist/Science/UM Microphysics +range=0: +sort-key=Panel-A04b +type=real + +[namelist:microphysics=orog_block] +compulsory=true +description=Account for low-level blocking in the Seeder Feeder scheme +help=Used by the seeder feeder precipitation enhancement scheme to determine + =whether to account for sub-grid orographic low-level blocking. + =Blocking occurs for Froude numbers (U/NH) below fcrit. + =The effect of blocking is to reduce the effective sub-grid hill height + =used to estimate the sub-grid orographic water mixing ratio. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A04e +trigger=namelist:microphysics=fcrit: .true. +type=logical + +[namelist:microphysics=orog_rain] +compulsory=true +description=Include Seeder Feeder orographic precipitation enhancement +help=This scheme estimates the extra water that would be condensed + =within a gridbox due to flow over sub-grid hills. + =This water is not added to the resolved cloud water mixing ratio but + =is used in an additional accretion (riming) call to produce extra + =rain (snow). Extra riming only occurs if orog_rime is true. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A04 +trigger=namelist:microphysics=orog_rime: .true.; + = namelist:microphysics=orog_block: .true.; + = namelist:microphysics=nsigmasf: .true.; + = namelist:microphysics=nscalesf: .true.; +type=logical + +[namelist:microphysics=orog_rime] +compulsory=true +description=Allow the seeder feeder scheme to enhance riming. +help=As standard, the seeder feeder scheme uses the sub-grid orographic + =water estimate to produce extra rain accretion. + =This switch allows the scheme to also produce extra snow via riming. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A04d +type=logical + +[namelist:microphysics=prog_tnuc] +compulsory=true +description=Turn on prognostic tnuc approach +help=By setting this switch to True, + =the heterogeneous nucleation temperature + =will be calculated as a function of dust distribution (instead + =of -10 deg cel) in the large-scale precipitation. + =This is further passed to the convection scheme (indexed + =using the model-level index of the lifting condensation level). + =In convection scheme, tnuc_new is passed through shallow,deep + =and mid convection schemes +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A01 +type=logical + +[namelist:microphysics=qcl_rime] +compulsory=true +description=Minimum qcl for riming +help=When the shape-dependent riming rates are used, + =this specifies how much of the qcl in a gridbox + =is available for the riming process. + =Only the fraction of qcl that is above + =qcl_rime is used to calculate the riming rate. +!kind=default +ns=namelist/Science/UM Microphysics +range=0:1e-02 +sort-key=Panel-A01c +type=real + +[namelist:microphysics=shape_rime] +compulsory=true +description=Use ice particle shape-dependent riming rate +help=This code makes the riming rate depend on the cross-sectional + =area of the ice/snow crystals. The parametrization of area + =in terms of particle size from Heymsfield and + =Miloshevich (J. Atmos. Sci., + =60,936 (2003)) is used. + =It also includes a minimum qcl, + =above which liquid water + =is available for riming. This follows the findings of + =Harimaya (J. Meteor. Japan, + =53(6), + =384-392) that + =there is a minimum droplet size for riming to occur. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A01 +trigger=namelist:microphysics=a_ratio_fac: .true.; + = namelist:microphysics=a_ratio_exp: .true.; + = namelist:microphysics=qcl_rime: .true.; +type=logical + +[namelist:microphysics=turb_gen_mixph] +compulsory=true +description=Include turbulent production of mixed phase cloud? +help=By setting this switch to True, + =the turbulent production of mixed phase + =cloud scheme is activated. +!kind=default +ns=namelist/Science/UM Microphysics +sort-key=Panel-A03a +trigger=namelist:microphysics=mp_dz_scal: .true.; +type=logical + +[namelist:microphysics=z_surf] +compulsory=true +description=Height (m) at which taper reaches ndrop_surf +help=This sets the height (m) above the surface at which the droplet taper + =reaches the value of ndrop_surf. The droplet number then remains + =constant at this value below this height. Setting at value of 0 + =will just result in model level 1 being used. + =Value must be <= z_peak_nd which is now hard-wired to 150.0 in UM code. + = + =In the, somewhat peculiar, case of drop number decreasing with height + =it will always taper to ndrop_surf at level 1. +!kind=default +ns=namelist/Science/UM Microphysics +range=0.0:150.0 +sort-key=Panel-A02b +type=real diff --git a/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/version30_31.py new file mode 100644 index 000000000..cb810f3ee --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/vn3.1/rose-meta.conf new file mode 100644 index 000000000..a52082e03 --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-orographic_drag/vn3.1/rose-meta.conf @@ -0,0 +1,161 @@ +#============================================================================== +# OROGRAPHIC GRAVITY WAVE AND BLOCKING DRAG +#============================================================================== + +[namelist:orographic_drag] +compulsory=true +description=Orographic drag parametrization configuration +ns=namelist/Science/Orographic drag +sort-key=Section-A09 +title=Orographic drag + +[namelist:orographic_drag=cd_flow_blocking] +compulsory=true +description=Flow blocking drag coefficient +help=Factor multiplying the orographic blocking drag. + = + =Reasonable values range from 1 to 10. + = + =Recommended value is 4.0. +!kind=default +sort-key=Panel-A00 +type=real + +[namelist:orographic_drag=fr_crit_gwd] +compulsory=true +description=Low-level critical Froude Number +help=The low-level critical Froude number is the Froude number + =below which orographic blocking drag occurs. + = + =It is computed using the subgrid mountain height (h), + =low-level averaged winds (U) and stability (N) using: + = + = F = U/Nh + = + =The larger the critical Froude number the higher the + =likelihood of flow blocking within a grid-box, and the + =larger the depth over which the blocking drag is applied. + = + =According to linear theory, the critical Froude number + =should be ~1.0. However, most operational configurations + =use a value of 4.0, as smaller values can lead to excessive + =drags in the lower stratosphere and insufficient drag near + =the surface. +!kind=default +range=0.5:10.0 +sort-key=Panel-A02 +type=real + +[namelist:orographic_drag=fr_sat_gwd] +compulsory=true +description=Critical Froude number for gravity wave saturation +help=The critical value of the vertically varying Froude number. + = + =This is used in the amplitude based saturation test for gravity + =wave breaking. Higher Froude numbers will result in larger + =gravity wave amplitudes before wave breaking occurs. + = + =Theoretically this should be approximately 1.0. + = + =Recommended value is 0.25. +!kind=default +range=0.1:10.0 +sort-key=Panel-A03 +type=real + +[namelist:orographic_drag=gwd_scaling] +compulsory=true +description=Surface stress amplitude scaling coefficient +help=Coefficient used to scale amplitude of orographic gravity wave + =surface stress. + =In theory, gwd_scaling should be a function of the subgrid mountain + =sharpness but here it is treated as a constant tuning coefficient. + = + =Theoretical values range from 0.9 for sharply peaked mountains to + =2.0 for broad mountains. + = + =Recommended value is 1. +!kind=default +range=0.0:10.0 +sort-key=Panel-A01 +type=real + +[namelist:orographic_drag=include_moisture] +description=Specify whether to use the dry buoyancy frequency (Nd) or + =whether to use an effective moist value that accounts for + =latent heating (Nmoist), either throughout the atmosphere + =or just at low-levels. +!enumeration=true +help=Setting this to 'dry' means that the dry value of the buoyancy + =frequency (Nd) is used everywhere. + =Setting this to 'lowmoist' means that Nmoist is used to calculate + =the low-level flow blocking drag and the total wave stress in a column, + =while using Nd to distribute that wave drag in the vertical. + =Setting this to 'moist' means that Nmoist is used everywhere in the scheme. + =Latent heating due to moist processes is accounted for by estimating how + =much of the sub-grid orographic displacement is saturated, and then + =calculating a weighted average of the dry and saturated values of the + =buoyancy frequency. + =This is physically more realistic for moist air masses and reduces the + =buoyancy frequency N. + =The saturated value is from Durran and Klemp (1982). +!kind=default +sort-key=Panel-A08 +value-titles=Use dry N value everywhere,Include latent heat at low-levels, + =Include latent heat everywhere +values='dry','lowmoist','moist' + +[namelist:orographic_drag=mountain_height_scaling] +compulsory=true +description=Sub-grid orographic standard deviation scaling factor +help=Factor which scales the standard deviation of the sub-grid orography. + =It provides an estimate of the average mountain height within a + =model grid box. + = + =This height defines the top of the near-surface layer of air + =which is impinging on the sub-grid orography. + = + =Recommended value is 2.5. +!kind=default +range=0.5:10.0 +sort-key=Panel-A04 +type=real + +[namelist:orographic_drag=orographic_blocking_heating] +compulsory=true +description=Apply heat dissipation + =(orographic blocking drag) +help=Account for frictional heat dissipation + =due to flow blocking by orography. + = + =Recommended that flow blocking heat + =dissipitation is enabled for most model + =configurations. +!kind=default +sort-key=Panel-A06 +type=logical + +[namelist:orographic_drag=orographic_gwd_heating] +compulsory=true +description=Apply heat dissipation + =(orographic gravity-wave drag) +help=Account for frictional heat dissipation + =due to orographic gravity waves. + = + =Recommended that gravity-wave heat + =dissipitation is enabled for most model + =configurations. +!kind=default +sort-key=Panel-A05 +type=logical + +[namelist:orographic_drag=vertical_smoothing] +compulsory=true +description=Smooth acceleration over a vertical wavelength +help=The scheme has an option to apply the acceleration due to gravity wave + =drag over one vertical wavelength. + = + =Recommended value is TRUE. +!kind=default +sort-key=Panel-A07 +type=logical diff --git a/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/version30_31.py new file mode 100644 index 000000000..22d54c15c --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/vn3.1/rose-meta.conf new file mode 100644 index 000000000..8f9f8c2ca --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-spectral_gwd/vn3.1/rose-meta.conf @@ -0,0 +1,91 @@ +#============================================================================== +# SPECTRAL GRAVITY WAVE DRAG: +#============================================================================== + +[namelist:spectral_gwd] +compulsory=true +description=Spectral gravity wave drag scheme options +ns=namelist/Science/UM Spectral gravity wave drag +sort-key=Section-A11 +title=Spectral Gravity Wave Drag + +[namelist:spectral_gwd=add_cgw] +compulsory=true +description=Activate total precipitation dependent variable gravity wave + =source flux + =WARNING: This is an experimental configuration with further + =refinements planned. Users who propose to activate this option + =are recommended to consult the code owner first. +help=False: applies the standard global invariant source for the + =spectral non-orographic gravity wave scheme. + = + =True: activates a new total precipitation source for the + =spectral non-orographic gravity wave scheme. +!kind=default +ns=namelist/Science/UM Spectral gravity wave drag +sort-key=Panel-A00 +trigger=namelist:spectral_gwd=cgw_scale_factor: .true.; +type=logical + +[namelist:spectral_gwd=cgw_scale_factor] +compulsory=true +description=Factor enhancement for conversion from total precipitation + =to gravity wave source flux +help="Factor enhancement for conversion from total precipitation" allows + =the total precipitation dependent variable gravity wave source + =to be adjusted about its default value (factor = 1.0). + = + =The permitted range is from 0.0 (switch total precipitation source + =off) to 10.0 (arbitrary upper limit) but, as for the global + =invariant factor, significant impact on the QBO period is expected + =for deviations about 1.0 of order ten percent. +!kind=default +ns=namelist/Science/UM Spectral gravity wave drag +range=0:10 +sort-key=Panel-A01 +type=real + +[namelist:spectral_gwd=ussp_heating] +compulsory=true +description=Apply heating due to non-orographic gravity-wave dissipation. +help=The 5A scheme includes the option to apply heating due to the frictional + =dissipation of gravity waves (and flow blocking drag). + = + =TRUE Turns on heating due to spectral gravity wave drag +!kind=default +sort-key=Panel-A02 +type=logical + +[namelist:spectral_gwd=ussp_launch_factor] +compulsory=true +description=Factor enhancement for global invariant wave launch amplitude +help=This allows the global source to be adjusted about its default value + =(factor = 1.0). + = + =The permitted range is from 0.0 (switch off globally invariant source) + =to 10.0 (spectrum saturated at launch level given current values) + =but significant impact on the QBO period is usual + =for deviations about 1.0 of order ten percent. +!kind=default +ns=namelist/Science/UM Spectral gravity wave drag +range=0:10 +sort-key=Panel-A03 +type=real + +[namelist:spectral_gwd=wavelstar] +compulsory=true +description=Characteristic (spectrum peak) wavelength (m) +help="Characteristic (spectrum peak) wavelength" allows adjustment of + =the global source spectrum shape by varying the transition to the + =(inverse cube of vertical wavenumber) tail about its default + =value (4300.00m). + = + =The default value is generally recommended: the ability to vary + =within a permitted range from 1000.0 (high wavenumber) + =to 10000.0 (low wavenumber - there is a cut-off at 20000.0) + =has been added only for perturbed parameter experiments. +!kind=default +ns=namelist/Science/UM Spectral gravity wave drag +range=1000:10000 +sort-key=Panel-A04 +type=real diff --git a/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/HEAD/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/HEAD/rose-meta.conf index c01f31b69..957c94aad 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/HEAD/rose-meta.conf +++ b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/HEAD/rose-meta.conf @@ -827,7 +827,8 @@ values='fd','fe' [namelist:stochastic_physics=skeb_level_bottom] compulsory=true description=Bottom level of SKEB calculations -help=Bottom level of SKEB calculations - model level a little above surface +help=The bottom pressure-level at which SKEB is active. + =A value of 1 corresponds to the lowest level of the model. ns=namelist/Science/Stochastic Physics/SKEB range=2:60 sort-key=Panel-A3a @@ -845,7 +846,7 @@ type=integer [namelist:stochastic_physics=skeb_level_top] compulsory=true description=Top level of SKEB calculations -help=Top level of SKEB calculations - model level at or just above tropopause +help=If the model has N layers, a value of N would correspond to the top layer. ns=namelist/Science/Stochastic Physics/SKEB range=30:200 sort-key=Panel-A3b @@ -963,12 +964,14 @@ type=integer [namelist:stochastic_physics=spt_level_bottom] compulsory=true -description=Bottom level where SPT is active - =See Help panel for details -help=Bottom level wehre SPT perturbations are applied. - =Though, the tapering at this level is 0 so effectively - =SPT perturbations start one level above, see help-panel - = of spt_level_begin_tapering_bottom. +description=Bottom level at which SPT is active +help=The bottom theta-level at which SPT perturbations are applied. + =A value of 0 would correspond to the surface, so a value of 2 means that + =perturbations are applied from the third theta-level and above. + =Note that the perturbations are actually tapered, so that at the level + =specified here the perturbations will still be 0, and SPT perturbations + =effectively start at one level above this specified value. + =For more information, see help-panel of spt_level_begin_tapering_bottom. ns=namelist/Science/Stochastic Physics/SPT range=2:60 sort-key=Panel-A6a @@ -976,12 +979,14 @@ type=integer [namelist:stochastic_physics=spt_level_top] compulsory=true -description=Top level where SPT is active - =See Help panel for details -help=Top level where SPT perturbations are applied. +description=Top level at which SPT is active +help=The top theta-level at which SPT perturbations are applied. + =If the model has N layers, a value of N would correspond to the top + =boundary. Note that the perturbations are actually tapered, so that at the + =level specified here the perturbations will still be 0, and SPT + =perturbations effectively start at one level below this specified value. =Though, the tapering at this level is 0 so effectively - =SPT perturbations start one level below, see help-panel - = of spt_level_begin_tapering_top. + =For more information, see help-panel of spt_level_begin_tapering_top. ns=namelist/Science/Stochastic Physics/SPT range=30:200 sort-key=Panel-A6d diff --git a/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/version30_31.py b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/version30_31.py new file mode 100644 index 000000000..857b5353b --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/version30_31.py @@ -0,0 +1,43 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/versions.py b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/versions.py +++ b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/vn3.1/rose-meta.conf b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/vn3.1/rose-meta.conf new file mode 100644 index 000000000..957c94aad --- /dev/null +++ b/interfaces/physics_schemes_interface/rose-meta/um-stochastic_physics/vn3.1/rose-meta.conf @@ -0,0 +1,1257 @@ +#============================================================================== +# Stochastic Physics: +#============================================================================== + +[namelist:stochastic_physics] +compulsory=true +description=Stochastic Physics +ns=namelist/Science/Stochastic Physics +sort-key=Section-A15 +title=Stochastic Physics + +[namelist:stochastic_physics=blpert_add_vertical_shape] +compulsory=true +description=Add vertical shape to perturbation profile +help=Within the option to perturb theta and moisture based on surface buoyancy + =flux, this perturbation can either be applied uniformly in the lower + =two-thirds levels of the boundary layer (blpert_add_vertical_shape set to + =false) or with a piece-wise linear shape that is zero at the surface and + =boundary layer top and equal to one in the middle (true). Note that the + =vertically integrated perturbation is very similar in both cases but the + =latter has less direct impact on the diagnosed screen level temperature. +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A7 +type=logical + +[namelist:stochastic_physics=blpert_decorrelation_time] +compulsory=true +description=Decorrelation timescale for perturbations (seconds) +help= +ns=namelist/Science/Stochastic Physics +range=0.0:1.0e+10 +sort-key=Panel-A7 +type=real + +[namelist:stochastic_physics=blpert_height_bottom] +compulsory=true +description=Minimum height from which to add perturbations (m) +fail-if=this > namelist:stochastic_physics=blpert_height_bottom +help=Minimum height in metres above the surface from which to add perturbations, + =typically set to 0m, ie from directly above the surface +ns=namelist/Science/Stochastic Physics +range=0.0:1.0e+10 +sort-key=Panel-A7 +type=real + +[namelist:stochastic_physics=blpert_height_top] +compulsory=true +description=Maximum height up to which to add perturbations (m) +fail-if=this < namelist:stochastic_physics=blpert_height_top +help=Maximum height in metres above the surface up to which to add perturbations, + =typically set to 1500m +ns=namelist/Science/Stochastic Physics +range=0.0:1.0e+10 +sort-key=Panel-A7 +type=real + +[namelist:stochastic_physics=blpert_max_magnitude] +compulsory=true +description=Maximum magnitude of theta perturbations +ns=namelist/Science/Stochastic Physics +range=0.0:1.0e+10 +sort-key=Panel-A7 +type=real + +[namelist:stochastic_physics=blpert_mesh_name] +compulsory=true +description=Name of the mesh used for computing random number field in boundary + =layer perturbation scheme +help= +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A7 +!string_length=default +type=character + +[namelist:stochastic_physics=blpert_noncumulus_points] +compulsory=true +description=In addition to cumulus-capped points, perturb non-cumulus-capped + =points, too. +help=If false, perturbations are only applied in regimes diagnosed as + =cumulus-capped. +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A7 +type=logical + +[namelist:stochastic_physics=blpert_npts_from_edge] +compulsory=true +description=Number of points from domain edge to apply perturbations +fail-if=this <0 ; +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A7 +type=integer + +[namelist:stochastic_physics=blpert_only_near_edge] +compulsory=true +description=Randomly perturb points only near the domain edges +fail-if=this and (namelist:boundaries=limited_area == "'.false.'"); +help=When stochastic pertubations are selected (using blpert_type), + =this switch makes them only be applied within + =blpert_npts_from_edge grid points from the domain boundaries +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A7 +trigger=namelist:stochastic_physics=blpert_npts_from_edge: .true. +type=logical + +[namelist:stochastic_physics=blpert_time_correlation] +compulsory=true +description=Apply time-correlated random perturbation + =If false, apply purely random sequence (no time-correlation) +help= +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A7 +trigger=namelist:stochastic_physics=blpert_decorrelation_time: .true. +type=logical + +[namelist:stochastic_physics=blpert_type] +compulsory=true +description=Main switch of boudary layer random perturbation scheme +!enumeration=true +help=Add random perturbations to the near surface field. These are either based + =on a fixed magnitude (blpert_max_magnitude) or the surface buoyancy flux. + =If they are based on the surface buoyancy flux, blpert_max_magnitude still + =provides the maximum possible value. A final option is also to perturb + =moisture. + =Perturbations can be applied on Cumulus points only or all points + =in the domain (depending on blpert_noncumulus_points). + =In the vertical they can be applied uniformly up to 2/3 of NTML (the number + =of levels in the boundary layer) or with a triangular vertical profile in + =the boundary layer. Perturbations will also only be applied between the + =heighs between blpert_height_bottom and blpert_height_top. + =Perturbations are created on a course mesh (blpert_mesh_name) and + =projected onto fine mesh without interpolation. +!kind=default +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A7 +trigger=namelist:stochastic_physics=blpert_mesh_name: 'theta_mag','theta_star','theta_and_moist' ; + =namelist:stochastic_physics=blpert_time_correlation: 'theta_mag','theta_star','theta_and_moist' ; + =namelist:stochastic_physics=blpert_only_near_edge: 'theta_mag','theta_star','theta_and_moist' ; + =namelist:stochastic_physics=blpert_noncumulus_points: 'theta_mag','theta_star','theta_and_moist' ; + =namelist:stochastic_physics=blpert_npts_from_edge: 'theta_mag','theta_star','theta_and_moist' ; + =namelist:stochastic_physics=blpert_height_bottom: 'theta_mag','theta_star','theta_and_moist' ; + =namelist:stochastic_physics=blpert_height_top: 'theta_mag','theta_star','theta_and_moist' ; + =namelist:stochastic_physics=blpert_add_vertical_shape: 'theta_and_moist' ; + =namelist:stochastic_physics=blpert_max_magnitude: 'theta_mag','theta_star','theta_and_moist' ; +value-titles=None,Perturb theta with fixed magnitude, + =Perturb theta based on surface buoyancy flux, + =Perturb theta and moisture based on surface buoyancy flux +values='off','theta_mag','theta_star','theta_and_moist' + +[namelist:stochastic_physics=ens_memb] +compulsory=true +description=Ensemble member +help=Ensemble member number +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A +type=integer + +[namelist:stochastic_physics=rp_bl_a_ent_1] +compulsory=true +description=Entrainment parameter A1 for RP; min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); + =this(3) > 1.0; + =this(1) < 0.01 +help=Parameter controlling entrainment parameter A1 in Boundary Layer scheme. + =Min, default and max values of bl_a_ent_1 are set here + =Recommended values are 0.1 / 0.23 / 0.4 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_a_ent_shr] +compulsory=true +description=Entrainment parameter bl_a_ent_shr for RP +help=Parameter controlling entrainment due to wind shear parameter bl_a_ent_shr + =in Boundary Layer scheme. This parameter varies with A1. Only a + =default and maximum value is needed for the scheme. The minimum + =is always zero. + =Default value of bl_a_ent_shr is set here - recommended value is 1.6 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_a_ent_shr_max] +compulsory=true +description=Entrainment parameter bl_a_ent_shr for RP max value +fail-if=this < namelist:stochastic_physics=rp_bl_a_ent_shr +help=Maximum Random Perturbation value for entrainment due to wind + =shear parameter bl_a_ent_shr in Boundary Layer scheme. + =Suggested/usual value is 5.0 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_cbl_mix_fac] +compulsory=true +description=Parameter controlling mixing in convective boundary layers + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling mixing in convective boundary layers: + =Changes the unstable tail functions in the boundary-layer so that + =the function varies between the 'conventional' and 'standard' + =subgrid schemes. RPb only. + =Recommended values are 0.0 / 0.5 / 1.0 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_cld_top_diffusion] +compulsory=true +description=Cloud-top diffusion control parameter for RP; min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); + =this(3) > 5.0; + =this(1) < 0.1 +help=Cloud-top diffusion control parameter in Boundary Layer scheme. + =Min, default and max values of rp_bl_cld_top_diffusion are set here + =Recommended values are 0.5 / 0.85 / 1.5 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_min_mix_length] +compulsory=true +description=Minimum mixing length for RP; min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling min mixing length for RP in the BL scheme. + =Min, default and max values of bl_min_mix_length are set here + =Recommended values are 8.0 / 40.0 / 120.0 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_neutral_mix_length] +compulsory=true +description=Neutral mixing length; min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter for neutral mixing length in Boundary Layer scheme. + =Min, default and max values of par_mezcla are set here + =Recommended values are 0.03 / 0.15 / 0.45 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_ricrit] +compulsory=true +description=Critical Richardson no. for RP; min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling critical Richardson no. in Boundary Layer scheme. + =Min, default and max values of ricrit are set here + =Recommended values are 0.25 / 1.0 / 2.0 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_smag_coef] +compulsory=true +description=Parameter for the Smagorinsky coefficient + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter representing the Smagorinsky coefficient + =Changes the coefficient (c_s or mix_factor) in the Smagorinsky + =turbulence scheme. RPb only. + =Recommended values are 0.01 / 0.2 / 1.0 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_bl_stable_ri_coef] +compulsory=true +description=Flux profile parameter for RP; min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Flux profile parameter in Boundary Layer scheme. + =Min, default and max values of rp_bl_stable_ri_coef are set here + =Recommended values are 5.0 / 10.0 / 40.0 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A05 +type=real + +[namelist:stochastic_physics=rp_callfreq] +compulsory=true +description=Interval between calls to the RP scheme (seconds) +help=The frequency of calls to the RP scheme in seconds. + =Must be a multiple of the timestep. +ns=namelist/Science/Stochastic Physics/RP +range=1: +sort-key=Panel-A01 +type=integer + +[namelist:stochastic_physics=rp_cycle_in] +compulsory=true +description=If true, + =then read in initial values of random parameters + =from a file. Must be used with stphseed = 0 or 1. + =Base name for the file is specified in rp_seed. +#fail-if=this ==".true." and namelist:stochastic_physics=rp_stphseed == 2 +# =#stphseed must be 0 or 1 +help=If set to true, + =then the intial values for the random parameters are + =read in from a file. Must be used with stphseed = 0 or 1. + =The file-name must take the format + =basename_CYCLE_IN_0000000000 + =where the basename is specified in rp_seed +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A03a +type=logical + +[namelist:stochastic_physics=rp_cycle_out] +compulsory=true +description=If true, + =then write out values of random parameters to a file + =at a specified time. + =File specified in rp_seed. +help=If set to true, then the random parameters will be written out to + =a file at a specified time (rp_cycle_tm). The file-name is based on + =rp_seed with the additional tag RP_CYCLE. +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A03b +trigger=namelist:stochastic_physics=rp_cycle_tm: .true. ; +type=logical + +[namelist:stochastic_physics=rp_cycle_tm] +compulsory=true +description=Time at which to write the RP parameters out + =to a file (seconds) +help=Length of time from the beginning of the forecast after + =which the set of random parameters are written out to a file. + =File name is specified in stphseed_file, + =with additional tag + =of RP_CYCLE. Can be used to initiate parameters in subsequent + =forecasts. Recommended value is 43200.0 (12 hours) +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A03c +type=integer + +[namelist:stochastic_physics=rp_decorr_ts] +compulsory=true +description=De-correlation timescale (seconds) for the + =random parameters scheme +fail-if=this < 1.0 +help=De-correlation timescale (seconds) used in the AR1 process for + =updating the parameter each time the random parameters scheme runs. + =Recommended value for global model is 216000.0 (60 hours) + =Recommended value for mogreps-uk is 604800.0 (1 week) +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A01b +type=real + +[namelist:stochastic_physics=rp_lsfc_alnir] +compulsory=true +description=RP for the JULES leaf reflection coefficient, alnir, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=this != namelist:jules_pftparm=alnir_io +help=The default value of rp_lsfc_alnir is set here - this should be the same + =as alnir_io (see jules_pftparm namelist). +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_alnir_max] +compulsory=true +description=Max RP for the JULES leaf reflection coefficient, alnir, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Maximum Random Perturbation value for JULES parameter alnir. Suggested values are + =0.5,0.45,0.7,0.7,0.7 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_alnir_min] +compulsory=true +description=Min RP for the JULES leaf reflection coefficient, alnir, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Minimum Random Perturbation value for JULES parameter alnir. Suggested values are + =0.3,0.2,0.3,0.3,0.3 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_alpar] +compulsory=true +description=RP for the JULES leaf reflection coefficient, alpar, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=this != namelist:jules_pftparm=alpar_io +help=The default value of rp_lsfc_alpar is set here - this should be the same + =as alpar (see jules_pftparm namelist). +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_alpar_max] +compulsory=true +description=Max RP for the JULES leaf reflection coefficient, alpar, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Maximum Random Perturbation value for JULES parameter alpar. Suggested values are + =0.15,0.11,0.2,0.2,0.2 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_alpar_min] +compulsory=true +description=Min RP for the JULES leaf reflection coefficient, alpar, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Minimum Random Perturbation value for JULES parameter alpar. Suggested values are + =0.05,0.04,0.05,0.05,0.05 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_lai_mult] +compulsory=true +description=RP value for the scaling parameter of the leaf area index + =ancillary. + =Input is a single value applied to all plant function types. +help=The default value for lai_mult is set here. Suggested value is + =1.0. +ns=namelist/Science/Stochastic Physics/RP +range=0.5:2.0 +sort-key=Panel-A10b +type=real + +[namelist:stochastic_physics=rp_lsfc_lai_mult_max] +compulsory=true +description=Max RP value for the scaling parameter of the leaf area index + =ancillary. + =Input is a single value applied to all plant function types. +help=Maximum Random Perturbation value for lai_mult. Suggested value is + =2.0. +ns=namelist/Science/Stochastic Physics/RP +range=1.0:2.0 +sort-key=Panel-A10b +type=real + +[namelist:stochastic_physics=rp_lsfc_lai_mult_min] +compulsory=true +description=Min RP value for the scaling parameter of the leaf area index + =ancillary. + =Input is a single value applied to all plant function types. +help=Minimum Random Perturbation value for lai_mult. Suggested value is + =0.5. +ns=namelist/Science/Stochastic Physics/RP +range=0.5:1.0 +sort-key=Panel-A10b +type=real + +[namelist:stochastic_physics=rp_lsfc_omega] +compulsory=true +description=RP for the JULES leaf scattering coefficient, omega, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=this != namelist:jules_pftparm=omega_io +help=The default value of rp_lsfc_omega is set here - this should be the same + =as omega (see jules_pftparm namelist). +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_omega_max] +compulsory=true +description=Max RP for the JULES leaf scattering coefficient, omega, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Maximum Random Perturbation value for JULES parameter omega. Suggested values are + =0.2,0.2,0.2,0.2,0.2 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_omega_min] +compulsory=true +description=Min RP for the JULES leaf scattering coefficient, omega, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Minimum Random Perturbation value for JULES parameter omega. Suggested values are + =0.05,0.05,0.1,0.1,0.1 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_omnir] +compulsory=true +description=RP for the JULES leaf scattering coefficient, omnir, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=this != namelist:jules_pftparm=omnir_io +help=The default value of rp_lsfc_omnir is set here - this should be the same + =as omnir (see jules_pftparm namelist). +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_omnir_max] +compulsory=true +description=Max RP for the JULES leaf scattering coefficient, omnir, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Maximum Random Perturbation value for JULES parameter omnir. Suggested values are + =0.9,0.6,0.9,0.9,0.9 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_omnir_min] +compulsory=true +description=Min RP for the JULES leaf scattering coefficient, omnir, on vegetation tiles + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Minimum Random Perturbation value for JULES parameter omnir. Suggested values are + =0.7,0.4,0.6,0.6,0.6 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_orog_drag_param] +compulsory=true +description=Orographic form drag parameter; + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the drag coefficient for + =orographic form drag + =Min, default and max values of orog_drag_param are set here + =Recommended values are 0.001 / 0.15 / 0.2 +length=3 +ns=namelist/UM Science Settings/section35/rp +sort-key=10 +type=real + +[namelist:stochastic_physics=rp_lsfc_z0_soil] +compulsory=true +description=RP for the roughness length for bare soil +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the roughness length for bare soil. + =Varies with z0v. + =Min, default and max values are set here + =The default value of z0_soil should equal the soil tile element of z0_nvg_io + =from the JULES namelist jules_nvegparm. + =Recommended values are 1.00000e-4 / 1.00000e-3 / 1.00000e-3 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_z0_urban_mult] +compulsory=true +description=RP for the roughness length for urban canyon and roof tiles +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the roughness length for urban canyon + =and roughness tile. For use with MORUSES only. + =Varies with z0v + =Min, default and max values are set here + =The default value should be 1.0. + =Recommended values are 0.5 / 1.0 / 1.5 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real +warn-if=this(2) != 1.0; # If the default it not 1.0, then the whole distribution of the ensemble will be shifted + +[namelist:stochastic_physics=rp_lsfc_z0hm_pft] +compulsory=true +description=RP for the ratio of the roughness length for heat to the + =roughness length for momentum. + =Input is an array of values corresponding to plant function type. +fail-if=this != namelist:jules_pftparm=z0hm_pft_io +help=The default value of z0hm_pft_io is set here - this should be the same + =as z0hm_pft_io for short vegetation (see jules namelist). +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_z0hm_pft_max] +compulsory=true +description=Max RP value for the ratio of the roughness length for + =heat to the roughness length for momentum. + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Maximum Random Perturbation value for z0hm_pft. Suggested value is 0.1 + =for short vegetation. +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_z0hm_pft_min] +compulsory=true +description=Min RP value for the ratio of the roughness length for heat + =to the roughness length for momentum. + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Minimum Random Perturbation value for z0hm_pft. Suggested value is 0.01 + =for short vegetation types. +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_z0hm_soil] +compulsory=true +description=RP for the roughness length for heat +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the roughness length for heat. + =Varies with z0v + =Min, default and max values are set here + =The default value of z0hm_soil should equal the soil tile + =element of z0hm_nvg_io from the JULES namelist jules_nvegparm. + =Recommended values are 0.01 / 0.2 / 0.5 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_z0v] +compulsory=true +description=RP for the vegetation tile roughness length for momentum + =Input is an array of values corresponding to plant function type. +fail-if=this != namelist:jules_pftparm=z0v_io +help=The default value of rp_lsfc_z0v is set here - this should be the same + =as z0v (see jules_pftparm namelist). +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_z0v_max] +compulsory=true +description=Max RP value for the vegetation tile roughness length for momentum + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Maximum Random Perturbation value for z0v. Suggested values are + =1.6,1.6,0.3,0.3 0.7 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_lsfc_z0v_min] +compulsory=true +description=Min RP value for the vegetation tile roughness length for momentum + =Input is an array of values corresponding to plant function type. +fail-if=len(this) != namelist:jules_surface_types=npft +help=Minimum Random Perturbation value for z0v. Suggested values are + =1.6,1.6,0.3,0.3 0.7 +length=: +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A10c +type=real + +[namelist:stochastic_physics=rp_mp_fxd_cld_num] +compulsory=true +description=Fixed cloud number parameter; + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the fixed cloud number + =in the CASIM microphysics scheme. + =Min, default and max values of fxd_cld_num_rp are set here + =Recommended values are 70.0e+06 / 150.0e+06 / 300.0e+06 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A08 +type=real + +[namelist:stochastic_physics=rp_mp_ice_fspd] +compulsory=true +description=Ice fallspeed parameter; + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the fall speed of ice + =in the CASIM microphysics scheme. + =Min, default and max values of ice_fspd_rp are set here + =Recommended values are 3600000.0 / 6000000.0 / 8400000.0 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A08 +type=real + +[namelist:stochastic_physics=rp_mp_mp_czero] +compulsory=true +description=Lagrangian structure function parameter; + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter used in the second-order Lagrangian structure + =function in the mixed-phase scheme + =Min, default and max values of mp_czero_rp are set here + =Recommended values are 4.0 / 10.0 / 10.0 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A08 +type=real + +[namelist:stochastic_physics=rp_mp_mpof] +compulsory=true +description=Mixed-phase overlap factor parameter; + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the mixed-phase overlap + =in the CASIM microphysics scheme. + =Min, default and max values of mpof_rp are set here + =Recommended values are 0.1 / 0.5 / 0.6 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A08 +type=real + +[namelist:stochastic_physics=rp_mp_ndrop_surf] +compulsory=true +description=Surface droplet number concentration; min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling surface droplet number concentration in + =the microphysics schemes. + =Min, default and max values of ndrop_surf are set here + =Recommended values for RAL3 are 2.0e+07 / 1.0e+07 / 10.0e+07 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A08 +type=real +warn-if=this(2) != namelist:microphysics=ndrop_surf + +[namelist:stochastic_physics=rp_mp_snow_fspd] +compulsory=true +description=Snow fallspeed parameter; + =min / default / max values +fail-if=(this(1) > this(2)) or (this(3) < this(2)); +help=Parameter controlling the fall speed of snow + =in the CASIM microphysics scheme. + =Min, default and max values of snow_fspd_rp are set here + =Recommended values are 7.2 / 12.0 / 16.8 +length=3 +ns=namelist/Science/Stochastic Physics/RP +sort-key=Panel-A08 +type=real + +[namelist:stochastic_physics=rp_ran_max] +compulsory=true +description=Number of independent RP variations +help=Number of independent RP variations +ns=namelist/Science/Stochastic Physics/RP +range=1:35 +sort-key=Panel-A04 +type=integer + +[namelist:stochastic_physics=skeb_add_increments] +compulsory=true +description=Add the SKEB increments to the prognostic winds +help=Set this to False for debugging purposes, increments will be + =generated but these will not be added to the flow. +ns=namelist/Science/Stochastic Physics/SKEB +sort-key=Panel-A1 +type=logical + +[namelist:stochastic_physics=skeb_br] +compulsory=true +description=SKEB Energy backscatter ratio +help=Backscatter ratio (as fraction of diss. energy) +ns=namelist/Science/Stochastic Physics/SKEB +range=0.01:1.0 +sort-key=Panel-A1c +type=real + +[namelist:stochastic_physics=skeb_convective_dissipation] +compulsory=true +description=Streamfunction modulation by convection +help=If TRUE include streamfunction modulation by convection +ns=namelist/Science/Stochastic Physics/SKEB +sort-key=Panel-A21 +trigger=namelist:stochastic_physics=skeb_convective_dissipation_factor: .true. ; + =namelist:stochastic_physics=skeb_convective_dissipation_modulation: .true. ; +type=logical + +[namelist:stochastic_physics=skeb_convective_dissipation_factor] +compulsory=true +description=Multiplication factor for convection dissipation +help=Multiplication factor for convection dissipation field (empirical value) +ns=namelist/Science/Stochastic Physics/SKEB +range=0.2:5.0 +sort-key=Panel-A21b +type=real + +[namelist:stochastic_physics=skeb_convective_dissipation_modulation] +compulsory=true +description=Convective dissipation rate factor for scalability across horizontal resolutions +help=A factor sqrt(216/res) modulates the convective dissipation rate, + =set to one if false +ns=namelist/Science/Stochastic Physics/SKEB +sort-key=Panel-A21c +type=logical + +[namelist:stochastic_physics=skeb_decorrelation_time] +compulsory=true +description=Decorrelation time in SKEB AR1 process +help=Tau is a decorrelation time (20000 sec = ~5.5 hrs is typical) +ns=namelist/Science/Stochastic Physics/SKEB +range=1.0e3:1.0e7 +sort-key=Panel-A2b +type=real + +[namelist:stochastic_physics=skeb_div_du] +compulsory=true +description=Method of divergent wind increment calculation +!enumeration=true +help= +ns=namelist/Science/Stochastic Physics/SKEB +sort-key=Panel-A22 +value-titles=Finite difference, Finite element +values='fd','fe' + +[namelist:stochastic_physics=skeb_level_bottom] +compulsory=true +description=Bottom level of SKEB calculations +help=The bottom pressure-level at which SKEB is active. + =A value of 1 corresponds to the lowest level of the model. +ns=namelist/Science/Stochastic Physics/SKEB +range=2:60 +sort-key=Panel-A3a +type=integer + +[namelist:stochastic_physics=skeb_level_bottom_cap] +compulsory=true +description=Bottom level of SKEB capping +help=Bottom level of SKEB calculations - model level a little above surface +ns=namelist/Science/Stochastic Physics/SKEB +range=2:60 +sort-key=Panel-A3a +type=integer + +[namelist:stochastic_physics=skeb_level_top] +compulsory=true +description=Top level of SKEB calculations +help=If the model has N layers, a value of N would correspond to the top layer. +ns=namelist/Science/Stochastic Physics/SKEB +range=30:200 +sort-key=Panel-A3b +type=integer + +[namelist:stochastic_physics=skeb_n_smoothing_iters] +compulsory=true +description=Iteration count for spatial smoothing in SKEB +help=Iteration count for spatial smoothing +ns=namelist/Science/Stochastic Physics/SKEB +range=1:10 +sort-key=Panel-A4a +type=integer + +[namelist:stochastic_physics=skeb_numerical_dissipation] +compulsory=true +description=Streamfunction modulation by numerical dissipation +!enumeration=true +help=If TRUE include streamfunction modulation by numerical dissipation +ns=namelist/Science/Stochastic Physics/SKEB +sort-key=Panel-A22 +trigger=namelist:stochastic_physics=skeb_numerical_dissipation_factor: 'fd','fe' ; +value-titles=None, Finite difference, Finite element +values='none','fd','fe' + +[namelist:stochastic_physics=skeb_numerical_dissipation_factor] +compulsory=true +description=Multiplication factor for SKEB numerical dissipation +help=Multiplication factor for numerical dissipation field (empirical value) +ns=namelist/Science/Stochastic Physics/SKEB +range=0.2:5.0 +sort-key=Panel-A22b +type=real + +[namelist:stochastic_physics=skeb_rot_du] +compulsory=true +description=Method of rotational wind increment calculation +!enumeration=true +help= +ns=namelist/Science/Stochastic Physics/SKEB +sort-key=Panel-A22 +value-titles=Finite difference, Finite element +values='fd','fe' + +[namelist:stochastic_physics=skeb_total_backscatter] +compulsory=true +description=Global-mean rate of energy backscatter in SKEB +help=Global-mean rate of energy backscatter in m**2 s**(-3) (1.e-4 typical) +ns=namelist/Science/Stochastic Physics/SKEB +range=1.0e-5:1.0e-3 +sort-key=Panel-A1b +type=real + +[namelist:stochastic_physics=spt_add_increments] +compulsory=true +description=Add increments to the flow +help=Set this to False for debugging purposes, increments will be + =generated but these will not be added to the flow. +ns=namelist/Science/Stochastic Physics/SPT +sort-key=Panel-A1 +type=logical + +[namelist:stochastic_physics=spt_convection_cfl_limit] +compulsory=true +description=Activate CFL constraint for convection increments +help=Check if the scaling of the convective mass flux by the + =SPT forcing pattern breaches the CFL limit. If it does, + =then the SPT perturbations are removed from this gridpoint. +ns=namelist/Science/Stochastic Physics/SPT +sort-key=Panel-A3a +type=logical + +[namelist:stochastic_physics=spt_decorrelation_time] +compulsory=true +description=Decorrelation time in SPT AR1 process +help=Tau is a decorrelation time (20000 sec = ~5.5 hrs is typical) +ns=namelist/Science/Stochastic Physics/SPT +range=1.0e3:1.0e7 +sort-key=Panel-A2b +type=real + +[namelist:stochastic_physics=spt_level_begin_tapering_bottom] +compulsory=true +description=Level where near-surface tapering starts +fail-if=this <= namelist:stochastic_physics=spt_level_bottom +help=At this level the lower tapering begins, going down from here to + = spt_level_bottom as + = + = (k - spt_level_bottom) / + = (spt_level_begin_tapering_bottom - spt_level_bottom) + = + = Where k is the level number, hence spt_level_begin_tapering_bottom + = level still has an amplitude of 1 and spt_level_bottom of 0. +ns=namelist/Science/Stochastic Physics/SPT +range=2:60 +sort-key=Panel-A6b +type=integer + +[namelist:stochastic_physics=spt_level_begin_tapering_top] +compulsory=true +description=Level where near-top tapering starts +fail-if=this >= namelist:stochastic_physics=spt_level_top +help=At this level the upper tapering begins, going up from here to + = spt_level_top as + = + = (k - spt_level_tapering_top) / + = (spt_level_top - spt_level_tapering_top) + = + = Where k is the level number, hence spt_level_begin_tapering_top + = level still has an amplitude of 1 and spt_level_top of 0. +ns=namelist/Science/Stochastic Physics/SPT +range=30:200 +sort-key=Panel-A6c +type=integer + +[namelist:stochastic_physics=spt_level_bottom] +compulsory=true +description=Bottom level at which SPT is active +help=The bottom theta-level at which SPT perturbations are applied. + =A value of 0 would correspond to the surface, so a value of 2 means that + =perturbations are applied from the third theta-level and above. + =Note that the perturbations are actually tapered, so that at the level + =specified here the perturbations will still be 0, and SPT perturbations + =effectively start at one level above this specified value. + =For more information, see help-panel of spt_level_begin_tapering_bottom. +ns=namelist/Science/Stochastic Physics/SPT +range=2:60 +sort-key=Panel-A6a +type=integer + +[namelist:stochastic_physics=spt_level_top] +compulsory=true +description=Top level at which SPT is active +help=The top theta-level at which SPT perturbations are applied. + =If the model has N layers, a value of N would correspond to the top + =boundary. Note that the perturbations are actually tapered, so that at the + =level specified here the perturbations will still be 0, and SPT + =perturbations effectively start at one level below this specified value. + =Though, the tapering at this level is 0 so effectively + =For more information, see help-panel of spt_level_begin_tapering_top. +ns=namelist/Science/Stochastic Physics/SPT +range=30:200 +sort-key=Panel-A6d +type=integer + +[namelist:stochastic_physics=spt_moisture_conservation] +compulsory=true +description=Activate water conservation in the column +help=It makes SPT to conserve the specific humidity q in the model column. +ns=namelist/Science/Stochastic Physics/SPT +sort-key=Panel-A3b +type=logical + +[namelist:stochastic_physics=spt_mse_conservation] +compulsory=true +description=Activate MSE conservation +help=It links SPT theta increments to q increments to conserve Moist Static Energy. +ns=namelist/Science/Stochastic Physics/SPT +sort-key=Panel-A3c +type=logical + +[namelist:stochastic_physics=spt_n_smoothing_iters] +compulsory=true +description=Number of smoothing iterations for the SPT pert +help=The number of iterations for the 1-2-1 filter to the SPT perturbations +ns=namelist/Science/Stochastic Physics/SPT +range=0:10 +sort-key=Panel-A5 +type=integer + +[namelist:stochastic_physics=spt_orog_forcing_pattern_thresh] +compulsory=true +description=Capping SPT pert above ABS(fp) and stddev_orog_thres +help=Set the threshold for the absolute value of the Forcing Pattern (FP) + = for SPT orographic capping. + = SPT perturbation are removed if FP >= spt_orog_forcing_pattern_thresh in areas + = where the standard deviation of subgrid orography is higher than the + = 'stddev_orog_thres' parameter (also contained in the 'namelist:stochastic_physics'). + = The default value is 0.5. +ns=namelist/Science/Stochastic Physics/SPT +range=0.1:1.0 +sort-key=Panel-A3d +type=real + +[namelist:stochastic_physics=spt_stddev_convection] +compulsory=true +description=Std dev. for the SPT perturbations to the Convection tendency +help=The Standard deviation of the forcing pattern applied to the + =Convection tendencies. To scale the pertubation +ns=namelist/Science/Stochastic Physics/SPT +range=0.01:10 +sort-key=Panel-A13b +type=real + +[namelist:stochastic_physics=spt_stddev_microphysics] +compulsory=true +description=Std dev. for the SPT perturbations to the Microphysics tendency +help=The Standard deviation of the forcing pattern applied to the + =Microphysics tendencies. To scale the pertubation +ns=namelist/Science/Stochastic Physics/SPT +range=0.01:10 +sort-key=Panel-A12b +type=real + +[namelist:stochastic_physics=spt_stddev_orog_thres] +compulsory=true +description=Capping SPT pert. above this value of subgrid std. dev. of orography +help=This parameter sets the threshold for the standard deviation of subgrid orography (sigma_orog) + = for SPT orographic capping. + = SPT perturbations are removed in areas where sigma_orog >= stddev_orog_thres and + = when the absolute value of the forcing pattern is above the namelist:stochastic_physics + = parameter 'spt_orog_forcing_pattern_thresh'. The default value is 500m +ns=namelist/Science/Stochastic Physics/SPT +range=100.0:4000.0 +sort-key=Panel-A3b +type=real + +[namelist:stochastic_physics=spt_stddev_radiation] +compulsory=true +description=Std dev. for the SPT perturbations to the Radiation tendency +help=The Standard deviation of the forcing pattern applied to the + =Radiative tendencies. To scale the pertubation +ns=namelist/Science/Stochastic Physics/SPT +range=0.01:10 +sort-key=Panel-A11b +type=real + +[namelist:stochastic_physics=spt_use_convection] +compulsory=true +description=Apply SPT perturbations to the T and q tendencies from convection +help=If false it does not add the perturbations from q and T of conv.tendencies +ns=namelist/Science/Stochastic Physics/SPT +sort-key=Panel-A13 +trigger=namelist:stochastic_physics=spt_stddev_convection: .true. ; +type=logical + +[namelist:stochastic_physics=spt_use_microphysics] +compulsory=true +description=Apply SPT perturbations to the T and q tendencies from Microphysics +help=If false it does not add the perturbations from q and T of microphysics + = (a.k.a. Large-Scale rain) tendencies +ns=namelist/Science/Stochastic Physics/SPT +sort-key=Panel-A12 +trigger=namelist:stochastic_physics=spt_stddev_microphysics: .true. ; +type=logical + +[namelist:stochastic_physics=spt_use_radiation] +compulsory=true +description=Apply SPT perturbations to the T and q tendencies from Radiation +help=If false it does not add the perturbations from q and T of Rad. tendencies +ns=namelist/Science/Stochastic Physics/SPT +sort-key=Panel-A11 +trigger=namelist:stochastic_physics=spt_stddev_radiation: .true. ; +type=logical + +[namelist:stochastic_physics=stph_n_max] +compulsory=true +description=Maximum wavenumber for the SPT and SKEB forcing pattern +help=This value is the maximum wavenumber of the spectral + =coefficients that define the forcing pattern + = + = It is recommended to have a value of 60 to only force + = the planetary and synoptic scales. + = Higher values may have a detrimental impact on the model + = runtime and usage of computational resources. +ns=namelist/Science/Stochastic Physics +range=2:150 +sort-key=Panel-A2a +type=integer + +[namelist:stochastic_physics=stph_n_min] +compulsory=true +description=Mininum wavenumber for the SKEB forcing pattern +help=This value is the maximum wavenumber of the spectral + =coefficients that define the forcing pattern. Note it is not + =applied to SPT as it uses a Gaussian distribution. + = + = It is recommended to have a value of 60 to only force + = the planetary and synoptic scales. + = Higher values may have a detrimental impact on the model + = runtime and usage of computational resources. +ns=namelist/Science/Stochastic Physics +range=1:150 +sort-key=Panel-A1a +type=integer + +[!namelist:stochastic_physics=stph_spectral_dim] +compulsory=false +description=SPT and SKEB spectral dimension (same) +expression=(namelist:stochastic_physics=stph_n_max + 1)*(namelist:stochastic_physics=stph_n_max + 2)/2-1 +help=The dimension of the spectral coefficients of the stochastic Forcing Pattern. + = As the (N+1)x(N+1) matrix of spectral coefficients x spherical harmonics is a triangular + = matrix as below, where N is max. wavenumber (stph_n_max) + = + = ------------------------------- + = | 0 | | | | | + = | 1 | 2 | | | | + = | 3 | 4 | 5 | | | + = | 6 | 7 | 8 | 9 | | + = | 10 | 11 | 12 | 13 | 14 | + = ------------------------------- + = + = It can be reshape to a vector of dimensions + = (N+1) + ((N+1)*2-(N+1))/2 = (N+1)*(N+2)/2 -1 + = For the diagonal, and lower half minus diagonal. +ns=namelist/Science/Stochastic Physics/SPT +type=integer + +[namelist:stochastic_physics=use_random_parameters] +compulsory=true +description=Switch controls use of the RP scheme +help=Main switch to control use of the Random Parameter (RP) scheme +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A +trigger=namelist:stochastic_physics=rp_bl_a_ent_1: .true. ; + =namelist:stochastic_physics=rp_bl_a_ent_shr_max: .true.; + =namelist:stochastic_physics=rp_bl_a_ent_shr: .true.; + =namelist:stochastic_physics=rp_bl_cbl_mix_fac: .true. ; + =namelist:stochastic_physics=rp_bl_cld_top_diffusion: .true. ; + =namelist:stochastic_physics=rp_bl_min_mix_length: .true. ; + =namelist:stochastic_physics=rp_bl_neutral_mix_length: .true. ; + =namelist:stochastic_physics=rp_bl_ricrit: .true. ; + =namelist:stochastic_physics=rp_bl_smag_coef: .true. ; + =namelist:stochastic_physics=rp_bl_stable_ri_coef: .true. ; + =namelist:stochastic_physics=rp_callfreq: .true. ; + =namelist:stochastic_physics=rp_cycle_in: .true. ; + =namelist:stochastic_physics=rp_cycle_out: .true. ; + =namelist:stochastic_physics=rp_cycle_tm: .true. ; + =namelist:stochastic_physics=rp_decorr_ts: .true. ; + =namelist:stochastic_physics=rp_lsfc_alnir_max: .true. ; + =namelist:stochastic_physics=rp_lsfc_alnir_min: .true. ; + =namelist:stochastic_physics=rp_lsfc_alnir: .true. ; + =namelist:stochastic_physics=rp_lsfc_alpar_max: .true. ; + =namelist:stochastic_physics=rp_lsfc_alpar_min: .true. ; + =namelist:stochastic_physics=rp_lsfc_alpar: .true. ; + =namelist:stochastic_physics=rp_lsfc_lai_mult_max: .true. ; + =namelist:stochastic_physics=rp_lsfc_lai_mult_min: .true. ; + =namelist:stochastic_physics=rp_lsfc_lai_mult: .true. ; + =namelist:stochastic_physics=rp_lsfc_omnir_max: .true. ; + =namelist:stochastic_physics=rp_lsfc_omnir_min: .true. ; + =namelist:stochastic_physics=rp_lsfc_omnir: .true. ; + =namelist:stochastic_physics=rp_lsfc_omega_max: .true. ; + =namelist:stochastic_physics=rp_lsfc_omega_min: .true. ; + =namelist:stochastic_physics=rp_lsfc_omega: .true. ; + =namelist:stochastic_physics=rp_lsfc_orog_drag_param: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0_soil: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0_urban_mult: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0hm_pft_max: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0hm_pft_min: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0hm_pft: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0hm_soil: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0v_max: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0v_min: .true. ; + =namelist:stochastic_physics=rp_lsfc_z0v: .true. ; + =namelist:stochastic_physics=rp_mp_ice_fspd: .true. ; + =namelist:stochastic_physics=rp_mp_fxd_cld_num: .true. ; + =namelist:stochastic_physics=rp_mp_mp_czero: .true. ; + =namelist:stochastic_physics=rp_mp_mpof: .true. ; + =namelist:stochastic_physics=rp_mp_ndrop_surf: .true. ; + =namelist:stochastic_physics=rp_mp_snow_fspd: .true. ; + =namelist:stochastic_physics=rp_ran_max: .true. ; +type=logical + +[namelist:stochastic_physics=use_skeb] +compulsory=true +description=Switch controls use of SKEB +help=Main switch to control use of Stochastic Kinetic Energy Backscatter v2 +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A +trigger=namelist:stochastic_physics=skeb_add_increments: .true. ; + =namelist:stochastic_physics=skeb_br: .true. ; + =namelist:stochastic_physics=skeb_convective_dissipation: .true. ; + =namelist:stochastic_physics=skeb_decorrelation_time: .true. ; + =namelist:stochastic_physics=skeb_div_du: .true. ; + =namelist:stochastic_physics=skeb_level_bottom: .true. ; + =namelist:stochastic_physics=skeb_level_bottom_cap: .true. ; + =namelist:stochastic_physics=skeb_level_top: .true. ; + =namelist:stochastic_physics=skeb_n_smoothing_iters: .true. ; + =namelist:stochastic_physics=skeb_numerical_dissipation: .true. ; + =namelist:stochastic_physics=skeb_rot_du: .true. ; + =namelist:stochastic_physics=skeb_total_backscatter: .true. ; +type=logical + +[namelist:stochastic_physics=use_spt] +compulsory=true +description=Switch controls use of SPT scheme +help=Main switch to control use of Stochastic Perturbation of Tendencies (SPT) scheme +ns=namelist/Science/Stochastic Physics +sort-key=Panel-A +trigger=namelist:stochastic_physics=spt_add_increments: .true. ; + =namelist:stochastic_physics=spt_convection_cfl_limit: .true. ; + =namelist:stochastic_physics=spt_decorrelation_time: .true. ; + =namelist:stochastic_physics=spt_level_bottom: .true. ; + =namelist:stochastic_physics=spt_level_begin_tapering_bottom: .true. ; + =namelist:stochastic_physics=spt_level_begin_tapering_top: .true. ; + =namelist:stochastic_physics=spt_level_top: .true. ; + =namelist:stochastic_physics=spt_moisture_conservation: .true. ; + =namelist:stochastic_physics=spt_mse_conservation: .true. ; + =namelist:stochastic_physics=spt_n_smoothing_iters: .true. ; + =namelist:stochastic_physics=spt_orog_forcing_pattern_thresh: .true. ; + =namelist:stochastic_physics=spt_stddev_convection: .true.; + =namelist:stochastic_physics=spt_stddev_microphysics: .true.; + =namelist:stochastic_physics=spt_stddev_orog_thres: .true. ; + =namelist:stochastic_physics=spt_stddev_radiation: .true.; + =namelist:stochastic_physics=spt_use_convection: .true.; + =namelist:stochastic_physics=spt_use_microphysics: .true.; + =namelist:stochastic_physics=spt_use_radiation: .true.; +type=logical diff --git a/interfaces/physics_schemes_interface/source/algorithm/aerosol_ukca_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/aerosol_ukca_alg_mod.x90 index a1a52f0e5..4a50a0f80 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/aerosol_ukca_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/aerosol_ukca_alg_mod.x90 @@ -69,12 +69,11 @@ contains get_detj_at_w3_fv use physics_constants_mod, only: get_rdz_w3 use aerosol_ukca_kernel_mod, only: aerosol_ukca_kernel_type - - use io_config_mod, only: subroutine_timers, use_xios_io, & - write_diag + use io_config_mod, only: use_xios_io, write_diag use xios, only: xios_date, xios_get_current_date, & xios_date_get_day_of_year - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use log_mod, only: log_event, LOG_LEVEL_DEBUG use chemistry_config_mod, only: chem_scheme, & @@ -466,8 +465,9 @@ contains integer( kind=i_def) :: jp1, jp2 ! Indices for photolysis fields type( field_type ) :: mr_ice + integer( tik ) :: id, id_photo, id_chem, id_diags - if ( subroutine_timers ) call timer('aerosol_ukca_alg') + if ( LPROF ) call start_timing( id, 'ukca' ) call log_event( 'Running UKCA aerosol', LOG_LEVEL_DEBUG ) @@ -1030,7 +1030,7 @@ contains if (mod( model_clock%get_step(), & chem_timestep/int(model_clock%get_seconds_per_step()) ) == 0) then - if ( subroutine_timers ) call timer('ukca_photolysis_alg') + if ( LPROF ) call start_timing( id_photo, 'ukca.photolysis_alg' ) ! FastJX scheme if (photol_scheme == photol_scheme_fastjx ) then @@ -1150,7 +1150,7 @@ contains end if ! photol_scheme = fastjx/ prescribed - if ( subroutine_timers ) call timer('ukca_photolysis_alg') + if ( LPROF ) call stop_timing( id_photo, 'ukca.photolysis_alg' ) end if ! Chem timestep @@ -1158,7 +1158,7 @@ contains ! Do UKCA time step - if ( subroutine_timers ) call timer('ukca_chemistry_alg') + if ( LPROF ) call start_timing( id_chem, 'ukca.chemistry_alg' ) call invoke(aerosol_ukca_kernel_type( o3p, & o1d, & o3, & @@ -1440,7 +1440,7 @@ contains emiss_so2_nat, & photol_rates )) - if ( subroutine_timers ) call timer('ukca_chemistry_alg') + if ( LPROF ) call stop_timing( id_chem, 'ukca.chemistry_alg' ) call um_sizes_init(1_i_def) ! Save time for reference at next step @@ -1457,7 +1457,11 @@ contains call log_field_minmax( LOG_LEVEL_DEBUG, ' CH4 Aft Chem ', ch4 ) end if + if ( LPROF ) call stop_timing( id, 'ukca' ) + if ( write_diag .and. use_xios_io ) then + if ( LPROF ) call start_timing( id_diags, 'diags.ukca' ) + ! Diagnostic output ! Chemistry diagnostics @@ -1652,11 +1656,11 @@ contains call pvol_du_acc_ins%write_field('aerosol__pvol_du_acc_ins') call pvol_du_cor_ins%write_field('aerosol__pvol_du_cor_ins') + if ( LPROF ) call stop_timing( id_diags, 'diags.ukca' ) end if ! write diag nullify( mesh ) - if ( subroutine_timers ) call timer('aerosol_ukca_alg') end subroutine aerosol_ukca_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/bl_exp_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/bl_exp_alg_mod.x90 index a514beb49..c1f05d8eb 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/bl_exp_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/bl_exp_alg_mod.x90 @@ -29,8 +29,7 @@ module bl_exp_alg_mod use bl_option_mod, only: l_noice_in_turb use um_sizes_init_mod, only: um_sizes_init - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_DEBUG use mesh_mod, only: mesh_type use model_clock_mod, only: model_clock_type @@ -67,7 +66,6 @@ contains !>@param[in,out] surface_fields Fields for surface scheme !>@param[in] recip_l_mo_sea Inverse Obukhov length over sea only !>@param[in] rhostar Surface density - !>@param[in h_blend_orog Orographic blending height !>@param[in] t1_sd_2d StDev of level 1 temperature !>@param[in] q1_sd_2d StDev of level 1 humidity !>@param[in] model_clock Time in the model @@ -76,8 +74,7 @@ contains microphysics_fields, dmr_mphys, orography_fields, & turbulence_fields, convection_fields, & cloud_fields, surface_fields, & - recip_l_mo_sea, & - rhostar, h_blend_orog, t1_sd_2d, q1_sd_2d, & + recip_l_mo_sea, rhostar, t1_sd_2d, q1_sd_2d, & model_clock) use bl_exp_kernel_mod, only: bl_exp_kernel_type @@ -101,7 +98,6 @@ contains type( field_type ), intent( in ) :: recip_l_mo_sea type( field_type ), intent( in ) :: rhostar - type( field_type ), intent( in ) :: h_blend_orog type( field_type ), intent( in ) :: t1_sd_2d type( field_type ), intent( in ) :: q1_sd_2d @@ -217,8 +213,9 @@ contains type( field_type ) :: mr_ice integer(i_def) :: ncells + integer(tik) :: id - if ( subroutine_timers ) call timer('bl_exp_alg') + if ( LPROF ) call start_timing( id, 'bl.explicit' ) call log_event( 'slow_physics: Running explicit Boundary layer', LOG_LEVEL_DEBUG ) @@ -380,7 +377,7 @@ contains cumulus, tile_fraction, sd_orog, & peak_to_trough_orog, silhouette_area_orog, & tile_temperature, rhostar, recip_l_mo_sea, & - h_blend_orog, t1_sd_2d, q1_sd_2d, & + t1_sd_2d, q1_sd_2d, & dtl_mphys, dmt_mphys, sw_heating_rate, & lw_heating_rate, cf_bulk, cf_liquid, & rh_crit, tnuc, tnuc_nlcl, & @@ -415,13 +412,13 @@ contains call um_sizes_init(1_i_def) if (formdrag == formdrag_dist_drag) then - if ( subroutine_timers ) call timer('bl_exp_alg') + if ( LPROF ) call stop_timing( id, 'bl.explicit' ) call theta%copy_field_properties(fd_tauz) call invoke(setval_c(fd_tauz, 0.0_r_def)) ! Calculate form drag stress in w2 call set_wind(fd_tau_w2,fd_taux,fd_tauy,fd_tauz) call invoke(inc_X_divideby_Y(fd_tau_w2, dA)) - if ( subroutine_timers ) call timer('bl_exp_alg') + if ( LPROF ) call start_timing( id, 'bl.explicit' ) end if ! Calculate explicit momentum diffusion on cell faces @@ -453,7 +450,7 @@ contains sea_v_current_ptr) ) end if - if ( subroutine_timers ) call timer('bl_exp_alg') + if ( LPROF ) call stop_timing( id, 'bl.explicit' ) ! output BL diagnostics if (write_diag .and. use_xios_io) then diff --git a/interfaces/physics_schemes_interface/source/algorithm/bl_imp_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/bl_imp_alg_mod.x90 index db83e0d3d..23cf608b0 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/bl_imp_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/bl_imp_alg_mod.x90 @@ -21,8 +21,7 @@ module bl_imp_alg_mod use timestepping_config_mod, only: outer_iterations use um_sizes_init_mod, only: um_sizes_init - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF ! xios output use io_config_mod, only: write_diag, use_xios_io, diagnostic_frequency use bl_imp_diags_mod, only: initialise_diags_for_bl_imp, & @@ -220,8 +219,10 @@ contains type( mesh_type ), pointer :: mesh => null() integer(i_def) :: loop, ncells logical(l_def) :: diag_step, flag_blpert + integer(tik) :: id - if ( subroutine_timers ) call timer("bl_imp_alg") + + if ( LPROF ) call start_timing( id, 'bl.implicit' ) call log_event( 'Running implicit Boundary layer', LOG_LEVEL_DEBUG ) @@ -330,7 +331,7 @@ contains call u_physics%copy_field_properties(du_conv_w2) if ( cv_scheme == cv_scheme_gregory_rowntree .or. & cv_scheme == cv_scheme_comorph ) then - if ( subroutine_timers ) call timer("bl_imp_alg") + if ( LPROF ) call stop_timing( id, 'bl.implicit' ) call theta%copy_field_properties(dw_conv) call invoke(setval_c(dw_conv, 0.0_r_def) ) call set_wind(du_conv_w2, du_conv, dv_conv, dw_conv) @@ -338,7 +339,7 @@ contains ! Set wind provides output in dynamics quantites, need to remove ! dA scaling for physics call invoke(inc_X_divideby_Y(du_conv_w2, dA) ) - if ( subroutine_timers ) call timer("bl_imp_alg") + if ( LPROF ) call start_timing( id, 'bl.implicit' ) else call invoke(setval_c(du_conv_w2, 0.0_r_def) ) end if @@ -476,7 +477,7 @@ contains setval_X(moist_flux_bl,fqw) ) end if - if ( subroutine_timers ) call timer("bl_imp_alg") + if ( LPROF ) call stop_timing( id, 'bl.implicit' ) ! Calculate and output fields on last iteration only if (use_xios_io .and. outer == outer_iterations) then diff --git a/interfaces/physics_schemes_interface/source/algorithm/blpert_main_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/blpert_main_alg_mod.x90 index 2159f6c56..ca8c73bad 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/blpert_main_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/blpert_main_alg_mod.x90 @@ -13,8 +13,7 @@ module blpert_main_alg_mod use field_mod, only: field_type, field_proxy_type use integer_field_mod, only: integer_field_type use clock_mod, only: clock_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -114,8 +113,9 @@ contains integer(i_def), parameter :: stencil_depth_edge = 1 integer(i_def), parameter :: stencil_depth_buff = 1 real(r_def) :: dt, auto_corr_coeff, tfac + integer(tik) :: id, id_diag - if ( subroutine_timers ) call timer("blpert_main_alg") + if ( LPROF ) call start_timing( id, 'stoch_phys.blpert' ) nullify(vector_space, coarse_vector_space, mesh, coarse_mesh, & twod_mesh, coarse_twod_mesh, local_mesh, mesh_map, & @@ -308,15 +308,18 @@ contains theta_star_surf, qv_star_surf, blpert_rand_fld, & pert_lev_bot, pert_lev_top, tfac) ) + if ( LPROF ) call stop_timing( id, 'stoch_phys.blpert' ) + !----------------------------------------------------------------! ! Write fields to diagnostics if requested !----------------------------------------------------------------! if (write_diag .and. use_xios_io) then + if ( LPROF ) call start_timing( id_diag, 'diags.blpert' ) call dtheta_base%write_field('stochastic__dtheta_base_blpert') call dmv_base%write_field('stochastic__dmv_base_blpert') - end if + if ( LPROF ) call stop_timing( id_diag, 'diags.blpert' ) - if ( subroutine_timers ) call timer("blpert_main_alg") + end if end subroutine blpert_main_alg end module blpert_main_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/bm_tau_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/bm_tau_alg_mod.x90 index eaaaa2814..2ef6b9a80 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/bm_tau_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/bm_tau_alg_mod.x90 @@ -11,8 +11,8 @@ module bm_tau_alg_mod use field_mod, only: field_type use field_collection_mod, only: field_collection_type use mr_indices_mod, only: nummr, imr_v, imr_cl, imr_ci, imr_s - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use mesh_mod, only: mesh_type use um_sizes_init_mod, only: um_sizes_init @@ -69,9 +69,10 @@ contains type( field_type ), pointer :: ni_mphys => null() type( mesh_type ), pointer :: mesh => null() - integer( kind=i_def ) :: ncells + integer( kind=i_def ) :: ncells + integer ( tik ) :: id - if ( subroutine_timers ) call timer('bm_tau_alg') + if ( LPROF ) call start_timing( id, 'cloud.bm_tau' ) call cloud_fields%get_field('frozen_fraction', cf_fro) call cloud_fields%get_field('tau_dec_bm', tau_dec_bm) @@ -102,7 +103,7 @@ contains call um_sizes_init(1_i_def) - if ( subroutine_timers ) call timer('bm_tau_alg') + if ( LPROF ) call stop_timing( id, 'cloud.bm_tau' ) end subroutine bm_tau_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/casim_activate_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/casim_activate_alg_mod.x90 index 743350347..df825a839 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/casim_activate_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/casim_activate_alg_mod.x90 @@ -11,9 +11,9 @@ module casim_activate_alg_mod use field_mod, only: field_type use field_collection_mod, only: field_collection_type use mr_indices_mod, only: nummr, imr_cl, imr_ci - use io_config_mod, only: subroutine_timers, write_diag, & - use_xios_io - use timer_mod, only: timer + use io_config_mod, only: write_diag, use_xios_io + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use log_mod, only: log_event, LOG_LEVEL_INFO use mesh_mod, only: mesh_type use sci_geometric_constants_mod, only: get_height_fv @@ -69,8 +69,9 @@ contains type( field_type ), pointer :: mci_init type( mesh_type ), pointer :: mesh + integer( tik ) :: id - if ( subroutine_timers ) call timer('casim_activate_alg') + if ( LPROF ) call start_timing( id, 'microphysics.casim_activate' ) ! For fixed CDNC or if we want to initialise the CDNC if (casim_cdnc_opt == casim_cdnc_opt_fixed .or. initialise) then @@ -119,7 +120,7 @@ contains end if - if ( subroutine_timers ) call timer('casim_activate_alg') + if ( LPROF ) call stop_timing( id, 'microphysics.casim_activate' ) end subroutine casim_activate_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/casim_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/casim_alg_mod.x90 index 8ad8ae789..056661535 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/casim_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/casim_alg_mod.x90 @@ -60,8 +60,7 @@ contains use microphysics_config_mod, only: turb_gen_mixph use um_sizes_init_mod, only: um_sizes_init - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_INFO implicit none @@ -122,8 +121,9 @@ contains type( field_type ) :: ls_graup_3d integer(kind=i_def) :: mesh_id, ncells + integer(tik) :: id_alg, id_diags - if ( subroutine_timers ) call timer("casim_alg") + if ( LPROF ) call start_timing( id_alg, 'microphysics.casim' ) call log_event( 'slow_physics: Running Microphysics', LOG_LEVEL_INFO ) @@ -216,12 +216,12 @@ contains call microphysics_fields%get_field('dmv_mphys', dmv_mphys) call invoke(setval_X(dmv_mphys, dmr_mphys(imr_v))) - if ( subroutine_timers ) call timer("casim_alg") + if ( LPROF ) call stop_timing( id_alg, 'microphysics.casim' ) ! Output microphysics diagnostics if (write_diag .and. use_xios_io) then - if ( subroutine_timers ) call timer("casim_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.microphysics' ) call output_diags_for_casim(ls_rain, ls_snow, ls_graup, & lsca_2d, refl_tot, refl_1km, & ls_rain_3d, ls_snow_3d, ls_graup_3d, & @@ -232,7 +232,7 @@ contains dmr_mphys(imr_g), dmr_mphys(imr_s), & superc_liq, superc_rain ) - if ( subroutine_timers ) call timer("casim_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.microphysics' ) end if end subroutine casim_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/cld_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/cld_alg_mod.x90 index 33071d015..07bb7b030 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/cld_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/cld_alg_mod.x90 @@ -14,11 +14,11 @@ module cld_alg_mod use mr_indices_mod, only: nummr, imr_v, imr_cl, imr_ci, & imr_r, imr_s use sci_enforce_lower_bound_kernel_mod, only: enforce_lower_bound_kernel_type - use io_config_mod, only: subroutine_timers, & - write_conservation_diag, & + use io_config_mod, only: write_conservation_diag, & write_diag, use_xios_io, & diagnostic_frequency - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use microphysics_config_mod, only: microphysics_casim use cloud_config_mod, only: scheme, & scheme_smith, & @@ -127,8 +127,9 @@ contains type( mesh_type ), pointer :: mesh => null() integer(i_def) :: i_mr, ncells character(str_def) :: name_ext + integer(tik) :: id - if ( subroutine_timers ) call timer('cld_alg') + if ( LPROF ) call start_timing( id, 'cloud' ) call log_event( 'End-of-timestep cloud update', LOG_LEVEL_DEBUG ) @@ -263,7 +264,7 @@ contains end if end if - if ( subroutine_timers ) call timer('cld_alg') + if ( LPROF ) call stop_timing( id, 'cloud' ) if ( write_diag .and. use_xios_io .and. & mod(step,diagnostic_frequency) == 0 .and. & diff --git a/interfaces/physics_schemes_interface/source/algorithm/conv_comorph_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/conv_comorph_alg_mod.x90 index 8fc190807..466e96012 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/conv_comorph_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/conv_comorph_alg_mod.x90 @@ -18,8 +18,7 @@ module conv_comorph_alg_mod use sci_geometric_constants_mod, only: get_height_fv, get_delta_at_wtheta use fs_continuity_mod, only: W3, Wtheta - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF ! xios output use io_config_mod, only: write_diag, use_xios_io use comorph_diags_mod, only: initialise_diags_for_comorph, & @@ -266,8 +265,9 @@ contains type( mesh_type ), pointer :: mesh integer(i_def) :: ncells + integer(tik) :: id - if ( subroutine_timers ) call timer("conv_comorph_alg") + if ( LPROF ) call start_timing( id, 'convection.comorph' ) call log_event( 'Running Comorph convection scheme', LOG_LEVEL_DEBUG ) @@ -630,7 +630,7 @@ contains call um_sizes_init(1_i_def) - if ( subroutine_timers ) call timer("conv_comorph_alg") + if ( LPROF ) call stop_timing( id, 'convection.comorph' ) ! output diagnostics on last iteration only if (write_diag .and. use_xios_io .and. outer == outer_iterations) then diff --git a/interfaces/physics_schemes_interface/source/algorithm/conv_gr_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/conv_gr_alg_mod.x90 index fbb5a8969..68a06a6ab 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/conv_gr_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/conv_gr_alg_mod.x90 @@ -13,13 +13,14 @@ module conv_gr_alg_mod use field_collection_mod, only: field_collection_type use mr_indices_mod, only: nummr, imr_v, imr_cl, imr_ci, imr_s use microphysics_config_mod, only: microphysics_casim + use um_sizes_init_mod, only: um_sizes_init use timestepping_config_mod, only: outer_iterations use sci_geometric_constants_mod, only: get_height_fv, get_delta_at_wtheta use fs_continuity_mod, only: W3, Wtheta - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF + ! xios output use io_config_mod, only: write_diag, use_xios_io use conv_diags_mod, only: initialise_diags_for_conv, & @@ -267,8 +268,10 @@ contains type( field_type ) :: mr_ice type( mesh_type ), pointer :: mesh => null() + integer(i_def) :: ncells + integer( tik) :: id - if ( subroutine_timers ) call timer("conv_gr_alg") + if ( LPROF ) call start_timing( id, 'convection.gr' ) call log_event( 'Running GR convection scheme', LOG_LEVEL_DEBUG ) @@ -507,7 +510,11 @@ contains if (microphysics_casim) then call invoke(inc_X_plus_Y(mr_ice, mr(imr_ci))) end if - + + ! Switch UM to running i-first on whole domain + ncells = mesh%get_last_edge_cell() + call um_sizes_init(ncells) + ! set increments to zero call invoke( setval_c(dt_conv, 0.0_r_def), & setval_c(dmv_conv, 0.0_r_def), & @@ -698,9 +705,12 @@ contains massflux_up_half, & massflux_up_cmpta, & cca_unadjusted, dth_conv_noshal, dmv_conv_noshal ) & - ) ! end of invoke + ) ! end of invoke + + ! Switch UM back to columns + call um_sizes_init(1_i_def) - if ( subroutine_timers ) call timer("conv_gr_alg") + if ( LPROF ) call stop_timing( id, 'convection.gr' ) ! output diagnostics on last iteration only if (write_diag .and. use_xios_io .and. outer == outer_iterations) then diff --git a/interfaces/physics_schemes_interface/source/algorithm/conv_ll_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/conv_ll_alg_mod.x90 index eee4bb96c..e8cc368ea 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/conv_ll_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/conv_ll_alg_mod.x90 @@ -12,8 +12,7 @@ module conv_ll_alg_mod use field_collection_mod, only: field_collection_type use mr_indices_mod, only: nummr, imr_v, imr_cl use timestepping_config_mod, only: outer_iterations - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF ! xios output use io_config_mod, only: write_diag, use_xios_io use log_mod, only: log_event, LOG_LEVEL_INFO @@ -59,8 +58,9 @@ contains type( field_type ), pointer :: dbcf_conv => null() type( field_type ), pointer :: conv_rain => null() type( field_type ), pointer :: conv_snow => null() + integer(tik) :: id_alg, id_diag - if ( subroutine_timers ) call timer("conv_ll_alg") + if ( LPROF ) call start_timing( id_alg, 'convection.alg' ) call log_event( 'Running LL convection scheme', LOG_LEVEL_INFO ) @@ -83,15 +83,17 @@ contains ! bulk fraction change is just the liquid change setval_X(dbcf_conv,dcfl_conv) ) + if ( LPROF ) call stop_timing( id_alg, 'convection.alg' ) + if (write_diag .and. use_xios_io .and. outer == outer_iterations) then + if ( LPROF ) call start_timing( id_diag, 'diags.convection' ) call dt_conv%write_field('convection__dt_conv') call dmv_conv%write_field('convection__dmv_conv') call conv_rain%write_field('convection__conv_rain') call conv_snow%write_field('convection__conv_snow') + if ( LPROF ) call stop_timing( id_diag, 'diags.convection' ) end if - if ( subroutine_timers ) call timer("conv_ll_alg") - end subroutine conv_ll_alg end module conv_ll_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/electric_main_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/electric_main_alg_mod.x90 index 12e4ffdbf..5a3dac459 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/electric_main_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/electric_main_alg_mod.x90 @@ -35,8 +35,7 @@ contains use electric_main_kernel_mod, only: electric_main_kernel_type use mr_indices_mod, only: imr_ci, imr_s, imr_g, nummr - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_INFO implicit none @@ -68,10 +67,12 @@ contains type(mesh_type), pointer :: mesh => null() + integer(tik) :: id + !-------------------------------------------------------------------------- ! End of declarations and start of the subroutine actually doing something !-------------------------------------------------------------------------- - if ( subroutine_timers ) call timer('electric_main_alg') + if ( LPROF ) call start_timing( id, 'electric' ) call log_event( 'slow_physics: Running Lightning Scheme', LOG_LEVEL_INFO ) @@ -111,8 +112,7 @@ contains fr1_mc_2d, fr2_mc_2d, gwp_2d, & tiwp_2d ) ) - - if ( subroutine_timers ) call timer('electric_main_alg') + if ( LPROF ) call stop_timing( id, 'electric' ) !--------------------------- ! Output Diagnostics diff --git a/interfaces/physics_schemes_interface/source/algorithm/flexchem_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/flexchem_alg_mod.x90 index 2668353ed..81f71b0d6 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/flexchem_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/flexchem_alg_mod.x90 @@ -10,9 +10,9 @@ module flexchem_alg_mod use chemistry_config_mod, only: flexchem_opt, flexchem_opt_bs1999 use field_mod, only: field_type use field_collection_mod, only: field_collection_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_INFO - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -53,8 +53,9 @@ contains type( field_type ), pointer :: rb type( field_type ), pointer :: tio type( field_type ), pointer :: vo + integer( tik ) :: id_chem, id_diags - if ( subroutine_timers ) call timer('flexchem_alg') + if ( LPROF ) call start_timing( id_chem, 'chemistry.flexchem' ) call log_event( 'Running flexible chemistry scheme', LOG_LEVEL_INFO ) @@ -81,6 +82,9 @@ contains ) ) end if + if ( LPROF ) call stop_timing( id_chem, 'chemistry.flexchem' ) + if ( LPROF ) call start_timing( id_diags, 'diags.flexchem' ) + ! Diagnostics call h2o%write_field('chemistry__h2o') call co%write_field('chemistry__co') @@ -96,7 +100,7 @@ contains call tio%write_field('chemistry__tio') call vo%write_field('chemistry__vo') - if ( subroutine_timers ) call timer('flexchem_alg') + if ( LPROF ) call stop_timing( id_diags, 'diags.flexchem' ) end subroutine flexchem_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/fsd_condensate_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/fsd_condensate_alg_mod.x90 index 48c93f5ed..4f2de9e2b 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/fsd_condensate_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/fsd_condensate_alg_mod.x90 @@ -33,8 +33,7 @@ contains subroutine fsd_condensate_alg( f_arr, cloud_fields, convection_fields ) use fsd_condensate_kernel_mod, only: fsd_condensate_kernel_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -51,9 +50,10 @@ contains type( field_type ), pointer :: sigma_mi type( field_type ), pointer :: cca - type( mesh_type), pointer :: mesh + type( mesh_type), pointer :: mesh + integer(tik) :: id - if ( subroutine_timers ) call timer("fsd_condensate_alg") + if ( LPROF ) call start_timing( id, 'cloud.fsd_condensate' ) ! Unpack fields call cloud_fields%get_field('area_fraction', area_fraction) @@ -79,7 +79,7 @@ contains nullify( mesh ) - if ( subroutine_timers ) call timer("fsd_condensate_alg") + if ( LPROF ) call stop_timing( id, 'cloud.fsd_condensate' ) end subroutine fsd_condensate_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/glomap_aerosol_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/glomap_aerosol_alg_mod.x90 index e7ee279c9..48d245b30 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/glomap_aerosol_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/glomap_aerosol_alg_mod.x90 @@ -13,11 +13,11 @@ module glomap_aerosol_alg_mod use field_collection_mod, only: field_collection_type use multires_coupling_config_mod, only: lowest_order_aero_flag, & coarse_rad_aerosol - use io_config_mod, only: subroutine_timers, & - use_xios_io, & + use io_config_mod, only: use_xios_io, & write_diag use mr_indices_mod, only: imr_ci, imr_v, nummr, imr_s - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use radiation_config_mod, only: n_radstep use aerosol_config_mod, only: n_radaer_step use microphysics_config_mod, only: microphysics_casim @@ -70,7 +70,6 @@ contains type( field_type ), pointer :: cf_bulk => null() type( field_type ), pointer :: cf_liquid => null() - type( field_type ), pointer :: rh_crit => null() ! Temporary unpacked fields from collection aerosol_fields type( field_type ), pointer :: n_nuc_sol => null() @@ -139,12 +138,12 @@ contains type( field_type ), pointer :: cf_bulk_aero => null() type( field_type ), pointer :: cf_liquid_aero => null() - type( field_type ), pointer :: rh_crit_aero => null() type( field_type ), pointer :: cloud_drop_no_conc_aero => null() - type( field_type ), target :: cf_bulk_coarse, cf_liquid_coarse, rh_crit_coarse, cloud_drop_no_conc_coarse - type( field_type ) :: mr_ice + type( field_type ), target :: cf_bulk_coarse, cf_liquid_coarse, cloud_drop_no_conc_coarse + type( field_type ) :: mr_ice + integer(tik) :: id_alg, id_diags - if ( subroutine_timers ) call timer('glomap_aerosol_alg') + if ( LPROF ) call start_timing( id_alg, 'aerosol.glomap_clim' ) ! Unpack fields from aerosol_fields call aerosol_fields%get_field('n_nuc_sol', n_nuc_sol) @@ -209,28 +208,23 @@ contains ! Unpack fields from cloud_fields call cloud_fields%get_field('bulk_fraction', cf_bulk) call cloud_fields%get_field('liquid_fraction', cf_liquid) - call cloud_fields%get_field('rh_crit', rh_crit) call aerosol_fields%get_field('cloud_drop_no_conc', cloud_drop_no_conc) ! Initialise coarse aerosol fields aerosol_mesh => exner_in_wth%get_mesh() wth_aero => function_space_collection%get_fs( aerosol_mesh, 0, 0, WTHETA ) call cf_bulk_coarse%initialise(vector_space = wth_aero) call cf_liquid_coarse%initialise(vector_space = wth_aero) - call rh_crit_coarse%initialise(vector_space = wth_aero) call cloud_drop_no_conc_coarse%initialise(vector_space = wth_aero) call map_scalar_intermesh(cf_bulk_coarse, cf_bulk) call map_scalar_intermesh(cf_liquid_coarse, cf_liquid) - call map_scalar_intermesh(rh_crit_coarse, rh_crit) call map_scalar_intermesh(cloud_drop_no_conc_coarse, cloud_drop_no_conc) cf_bulk_aero => cf_bulk_coarse cf_liquid_aero => cf_liquid_coarse - rh_crit_aero => rh_crit_coarse cloud_drop_no_conc_aero => cloud_drop_no_conc_coarse else ! Unpack fields from cloud_fields call cloud_fields%get_field('bulk_fraction', cf_bulk_aero) call cloud_fields%get_field('liquid_fraction', cf_liquid_aero) - call cloud_fields%get_field('rh_crit', rh_crit_aero) call aerosol_fields%get_field('cloud_drop_no_conc', cloud_drop_no_conc_aero) end if @@ -256,7 +250,6 @@ contains exner_in_wth, & cf_bulk_aero, & cf_liquid_aero, & - rh_crit_aero, & mr_n(imr_v), & mr_ice, & n_nuc_sol, & @@ -320,10 +313,10 @@ contains if ( coarse_rad_aerosol ) then call map_scalar_intermesh(cloud_drop_no_conc, cloud_drop_no_conc_aero, lowest_order_flag=lowest_order_aero_flag) end if - if ( subroutine_timers ) call timer('glomap_aerosol_alg') + if ( LPROF ) call stop_timing( id_alg, 'aerosol.glomap_clim' ) if ( write_diag .and. use_xios_io ) then - if ( subroutine_timers ) call timer("glomap_aerosol_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.glomap_clim' ) ! Diagnostic output call n_nuc_sol%write_field('aerosol__n_nuc_sol') @@ -377,7 +370,7 @@ contains call cloud_drop_no_conc_aero%write_field('aerosol__cloud_drop_no_conc') end if - if ( subroutine_timers ) call timer("glomap_aerosol_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.glomap_clim' ) end if end subroutine glomap_aerosol_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/locate_tropopause_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/locate_tropopause_alg_mod.x90 index fa540d1c0..56b535f63 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/locate_tropopause_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/locate_tropopause_alg_mod.x90 @@ -19,8 +19,7 @@ use mesh_mod, only: mesh_type use field_parent_mod, only: write_interface use sci_geometric_constants_mod, only: get_height_fv use locate_tropopause_kernel_mod, only: locate_tropopause_kernel_type -use io_config_mod, only: subroutine_timers -use timer_mod, only: timer +use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none private @@ -45,8 +44,9 @@ subroutine locate_tropopause_alg(trop_level, theta, exner_in_wth, twod_mesh) type( field_type ), pointer :: height_wth => null() type(function_space_type), pointer :: vector_space => null() procedure(write_interface), pointer :: write_diag_behaviour => null() + integer(tik) :: id_alg, id_diags - if ( subroutine_timers ) call timer("locate_tropopause_alg") + if ( LPROF ) call start_timing( id_alg, 'locate_tropopause' ) height_wth => get_height_fv(Wtheta, theta%get_mesh_id()) @@ -55,15 +55,14 @@ subroutine locate_tropopause_alg(trop_level, theta, exner_in_wth, twod_mesh) call invoke( locate_tropopause_kernel_type( theta, exner_in_wth, & height_wth, trop_level ) ) - - if ( subroutine_timers ) call timer("locate_tropopause_alg") + if ( LPROF ) call stop_timing( id_alg, 'locate_tropopause' ) if (write_diag .and. use_xios_io) then - if ( subroutine_timers ) call timer("locate_tropopause_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.locate_tropopause' ) write_diag_behaviour => write_field_generic call trop_level%set_write_behaviour(write_diag_behaviour) call trop_level%write_field('processed__trop_level') - if ( subroutine_timers ) call timer("locate_tropopause_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.locate_tropopause' ) end if end subroutine locate_tropopause_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/methox_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/methox_alg_mod.x90 index 07759e221..237f1d635 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/methox_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/methox_alg_mod.x90 @@ -10,9 +10,7 @@ module methox_alg_mod use field_mod, only: field_type use mr_indices_mod, only: nummr, imr_v use io_config_mod, only: write_diag, use_xios_io - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer - + use timing_mod, only: start_timing, stop_timing, tik, LPROF use constants_mod, only: r_def, i_def, pi, l_def use extrusion_config_mod, only: domain_height, number_of_layers use level_heights_mod, only: eta_theta_levels @@ -83,8 +81,9 @@ contains !Internal variables integer(kind=i_def) :: k real(kind=r_def) :: pressure, dt + integer(tik) :: id_alg, id_diags - if ( subroutine_timers ) call timer('methox_alg') + if ( LPROF ) call start_timing( id_alg, 'methane_oxidation' ) ! If required, calculate the rate coefficients ! (assumed to vary only with pressure) @@ -143,13 +142,15 @@ contains ! Calculate methane oxidation increment call invoke(methox_kernel_type(dmv_methox, mr(imr_v), dt)) + if ( LPROF ) call stop_timing( id_alg, 'methane_oxidation' ) + ! Output diagnostic if requested if (write_diag .and. use_xios_io) then + if ( LPROF ) call start_timing( id_diags, 'diags.methox' ) call dmv_methox%write_field('processed__dmv_methox') + if ( LPROF ) call stop_timing( id_diags, 'diags.methox' ) end if - if ( subroutine_timers ) call timer('methox_alg') - end subroutine methox_alg end module methox_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/mphys_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/mphys_alg_mod.x90 index 37f37f856..af353f280 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/mphys_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/mphys_alg_mod.x90 @@ -65,8 +65,7 @@ contains use cloud_config_mod, only: mphys_erosion use microphysics_config_mod, only: turb_gen_mixph, prog_tnuc - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_DEBUG implicit none @@ -139,8 +138,9 @@ contains type( field_type ) :: pressure_inc type(mesh_type), pointer :: mesh => null() + integer(tik) :: id - if ( subroutine_timers ) call timer("mphys_alg") + if ( LPROF ) call start_timing( id, 'microphysics.wb' ) call log_event( 'slow_physics: Running Microphysics', LOG_LEVEL_DEBUG ) @@ -260,7 +260,7 @@ contains call microphysics_fields%get_field('dmv_mphys', dmv_mphys) call invoke(setval_X(dmv_mphys, dmr_mphys(imr_v))) - if ( subroutine_timers ) call timer("mphys_alg") + if ( LPROF ) call stop_timing( id, 'microphysics.wb' ) ! Output microphysics diagnostics if (write_diag .and. use_xios_io) then diff --git a/interfaces/physics_schemes_interface/source/algorithm/orographic_drag_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/orographic_drag_alg_mod.x90 index 1f45816fe..ac7b24810 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/orographic_drag_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/orographic_drag_alg_mod.x90 @@ -12,8 +12,7 @@ module orographic_drag_alg_mod use mr_indices_mod, only: nummr, imr_v, imr_cl, imr_ci, imr_s use microphysics_config_mod, only: microphysics_casim use psykal_lite_phys_mod, only: invoke_orographic_drag_kernel - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_DEBUG use mesh_mod, only: mesh_type @@ -95,9 +94,9 @@ contains type( field_type ) :: mr_ice type( mesh_type ), pointer :: mesh => null() + integer( tik ) :: id - - if ( subroutine_timers ) call timer("orographic_drag_alg") + if ( LPROF ) call start_timing( id, 'orographic_drag' ) call log_event( 'slow_physics: Running Orographic drag', LOG_LEVEL_DEBUG ) @@ -177,7 +176,7 @@ contains X_divideby_Y (dtheta_orographic_drag, dtemp_orographic_drag, & exner_in_wth) ) - if ( subroutine_timers ) call timer("orographic_drag_alg") + if ( LPROF ) call stop_timing( id, 'orographic_drag' ) if (write_diag .and. use_xios_io) then diff --git a/interfaces/physics_schemes_interface/source/algorithm/pc2_checks_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/pc2_checks_alg_mod.x90 index 9f2472624..3cd40a3ce 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/pc2_checks_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/pc2_checks_alg_mod.x90 @@ -54,8 +54,7 @@ contains use pc2_checks_kernel_mod, only: pc2_checks_kernel_type use mr_indices_mod, only: imr_v, imr_cl, imr_ci, nummr, imr_s - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -80,8 +79,9 @@ contains type( field_type ), pointer :: liquid_fraction => null() type( field_type ), pointer :: frozen_fraction => null() type( field_type ), pointer :: bulk_fraction => null() + integer( tik ) :: id_alg, id_diags - if ( subroutine_timers ) call timer("pc2_checks_alg") + if ( LPROF ) call start_timing( id_alg, 'cloud.pc2_checks' ) ! Unpack fields call derived_fields%get_field('exner_in_wth', exner_in_wth) @@ -118,10 +118,10 @@ contains dcff_pc2_inc, & dbcf_pc2_inc ) ) - if ( subroutine_timers ) call timer("pc2_checks_alg") + if ( LPROF ) call stop_timing( id_alg, 'cloud.pc2_checks' ) if ( write_diag .and. use_xios_io ) then - if ( subroutine_timers ) call timer("pc2_checks_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.pc2_checks' ) call dtheta_pc2_inc%write_field('cloud__dtheta_pc2_checks') call dmv_pc2_inc%write_field('cloud__dmv_pc2_checks') call dmcl_pc2_inc%write_field('cloud__dmcl_pc2_checks') @@ -130,7 +130,7 @@ contains call dcfl_pc2_inc%write_field('cloud__dcfl_pc2_checks') call dcff_pc2_inc%write_field('cloud__dcff_pc2_checks') call dbcf_pc2_inc%write_field('cloud__dbcf_pc2_checks') - if ( subroutine_timers ) call timer("pc2_checks_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.pc2_checks' ) end if end subroutine pc2_checks_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/pc2_conv_coupling_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/pc2_conv_coupling_alg_mod.x90 index d18891bdd..6941a9d91 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/pc2_conv_coupling_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/pc2_conv_coupling_alg_mod.x90 @@ -40,8 +40,8 @@ contains convection_fields, cloud_fields, dt ) use constants_mod, only: i_def - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use pc2_conv_coupling_kernel_mod, only: pc2_conv_coupling_kernel_type use casim_conv_inc_kernel_mod, only: casim_conv_inc_kernel_type @@ -73,8 +73,9 @@ contains type(mesh_type), pointer :: mesh => null() integer(i_def) :: ncells + integer(tik) :: id_alg, id_diags - if ( subroutine_timers ) call timer ("pc2_conv_coupling_alg") + if ( LPROF ) call start_timing( id_alg, 'cloud.pc2_conv' ) call derived_fields%get_field('exner_in_wth', exner_wth) call derived_fields%get_field('theta_star', theta_star) @@ -133,10 +134,10 @@ contains call invoke(inc_X_plus_Y(mr(imr_s), dms_conv)) end if - if ( subroutine_timers ) call timer ("pc2_conv_coupling_alg") + if ( LPROF ) call stop_timing( id_alg, 'cloud.pc2_conv' ) if ( write_diag .and. use_xios_io ) then - if ( subroutine_timers ) call timer("pc2_conv_coupling_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.pc2_conv' ) call dt_conv%write_field('cloud__dt_pc2_conv_coupling') call dmv_conv%write_field('cloud__dmv_pc2_conv_coupling') call dmcl_conv%write_field('cloud__dmcl_pc2_conv_coupling') @@ -144,7 +145,7 @@ contains call dcfl_conv%write_field('cloud__dcfl_pc2_conv_coupling') call dcff_conv%write_field('cloud__dcff_pc2_conv_coupling') call dbcf_conv%write_field('cloud__dbcf_pc2_conv_coupling') - if ( subroutine_timers ) call timer("pc2_conv_coupling_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.pc2_conv' ) end if end subroutine pc2_conv_coupling_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/pc2_initiation_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/pc2_initiation_alg_mod.x90 index d6101365f..762245e56 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/pc2_initiation_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/pc2_initiation_alg_mod.x90 @@ -60,8 +60,7 @@ contains use pc2_initiation_kernel_mod, only: pc2_initiation_kernel_type use mr_indices_mod, only: imr_v, imr_cl, imr_ci, imr_s, nummr - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -116,8 +115,9 @@ contains type( mesh_type ), pointer :: mesh => null() integer( kind=i_def ) :: ncells + integer( tik ) :: id_alg, id_diags - if ( subroutine_timers ) call timer("pc2_initiation_alg") + if ( LPROF ) call start_timing( id_alg, 'cloud.pc2_initiation' ) ! Unpack fields call derived_fields%get_field('exner_wth_n', exner_wth_n) @@ -218,10 +218,10 @@ contains call um_sizes_init(1_i_def) - if ( subroutine_timers ) call timer("pc2_initiation_alg") + if ( LPROF ) call stop_timing( id_alg, 'cloud.pc2_initiation' ) if ( write_diag .and. use_xios_io ) then - if ( subroutine_timers ) call timer("pc2_initiation_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.pc2_initiation' ) call dtheta_pc2_inc%write_field('cloud__dtheta_pc2_initiation'//trim(name_ext)) call dmv_pc2_inc%write_field('cloud__dmv_pc2_initiation'//trim(name_ext)) call dmcl_pc2_inc%write_field('cloud__dmcl_pc2_initiation'//trim(name_ext)) @@ -230,7 +230,7 @@ contains call dcfl_pc2_inc%write_field('cloud__dcfl_pc2_initiation'//trim(name_ext)) call dcff_pc2_inc%write_field('cloud__dcff_pc2_initiation'//trim(name_ext)) call dbcf_pc2_inc%write_field('cloud__dbcf_pc2_initiation'//trim(name_ext)) - if ( subroutine_timers ) call timer("pc2_initiation_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.pc2_initiation' ) end if nullify( mesh ) diff --git a/interfaces/physics_schemes_interface/source/algorithm/pc2_pressure_forcing_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/pc2_pressure_forcing_alg_mod.x90 index ffc3f8865..55315b694 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/pc2_pressure_forcing_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/pc2_pressure_forcing_alg_mod.x90 @@ -39,8 +39,7 @@ contains use pc2_homogeneous_kernel_mod, only: pc2_homogeneous_kernel_type use mr_indices_mod, only: imr_v, imr_cl, nummr - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -69,8 +68,9 @@ contains type( field_type ), pointer :: frozen_fraction => null() type( field_type ), pointer :: bulk_fraction => null() type( field_type ), pointer :: exner_after_slow_wth => null() + integer( tik) :: id_alg, id_diags - if ( subroutine_timers ) call timer("pc2_pressure_forcing_alg") + if ( LPROF ) call start_timing( id_alg, 'cloud.pc2_pressure' ) ! Unpack fields call cloud_fields%get_field('liquid_fraction', liquid_fraction) @@ -126,16 +126,16 @@ contains inc_X_plus_Y(liquid_fraction, dcfl_pc2_inc), & inc_X_plus_Y(bulk_fraction, dbcf_pc2_inc) ) - if ( subroutine_timers ) call timer("pc2_pressure_forcing_alg") + if ( LPROF ) call stop_timing( id_alg, 'cloud.pc2_pressure' ) if ( write_diag .and. use_xios_io ) then - if ( subroutine_timers ) call timer("pc2_pressure_forcing_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.pc2_pressure' ) call dtheta_pc2_inc%write_field('cloud__dtheta_pc2_pressure_change'//trim(name_ext)) call dmv_pc2_inc%write_field('cloud__dmv_pc2_pressure_change'//trim(name_ext)) call dmcl_pc2_inc%write_field('cloud__dmcl_pc2_pressure_change'//trim(name_ext)) call dcfl_pc2_inc%write_field('cloud__dcfl_pc2_pressure_change'//trim(name_ext)) call dbcf_pc2_inc%write_field('cloud__dbcf_pc2_pressure_change'//trim(name_ext)) - if ( subroutine_timers ) call timer("pc2_pressure_forcing_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.pc2_pressure' ) end if end subroutine pc2_pressure_forcing_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/pc2_rad_response_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/pc2_rad_response_alg_mod.x90 index d6f83e560..343e03e60 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/pc2_rad_response_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/pc2_rad_response_alg_mod.x90 @@ -50,8 +50,7 @@ contains use pc2_homogeneous_kernel_mod, only: pc2_homogeneous_kernel_type use mr_indices_mod, only: imr_v, imr_cl, imr_ci, nummr - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -80,8 +79,9 @@ contains type( field_type ), pointer :: liquid_fraction => null() type( field_type ), pointer :: frozen_fraction => null() type( field_type ), pointer :: bulk_fraction => null() + integer( tik ) :: id_alg, id_diags - if ( subroutine_timers ) call timer("pc2_rad_response_alg") + if ( LPROF ) call start_timing( id_alg, 'cloud.pc2_radiation' ) ! Unpack fields call cloud_fields%get_field('liquid_fraction', liquid_fraction) @@ -124,16 +124,16 @@ contains ! N.B. We are not updating the variables that came in, just ! providing increments that need to be added on later. - if ( subroutine_timers ) call timer("pc2_rad_response_alg") + if ( LPROF ) call stop_timing( id_alg, 'cloud.pc2_radiation' ) if ( write_diag .and. use_xios_io ) then - if ( subroutine_timers ) call timer("pc2_rad_response_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.pc2_radiation' ) call dtheta_pc2_inc%write_field('cloud__dtheta_pc2_rad') call dmv_pc2_inc%write_field('cloud__dmv_pc2_rad') call dmcl_pc2_inc%write_field('cloud__dmcl_pc2_rad') call dcfl_pc2_inc%write_field('cloud__dcfl_pc2_rad') call dbcf_pc2_inc%write_field('cloud__dbcf_pc2_rad') - if ( subroutine_timers ) call timer("pc2_rad_response_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.pc2_radiation' ) end if end subroutine pc2_rad_response_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/pmsl_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/pmsl_alg_mod.x90 index 27264d3ce..5ffc38a98 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/pmsl_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/pmsl_alg_mod.x90 @@ -9,8 +9,8 @@ module pmsl_alg_mod use field_mod, only: field_type use field_collection_mod, only: field_collection_type - use io_config_mod, only: write_diag, use_xios_io,subroutine_timers - use timer_mod, only: timer + use io_config_mod, only: write_diag, use_xios_io + use timing_mod, only: start_timing, stop_timing, tik, LPROF use extrusion_config_mod, only: number_of_layers, domain_height use constants_mod, only: r_def, i_def use level_heights_mod, only: eta_theta_levels @@ -80,8 +80,9 @@ contains real(kind=r_def), parameter :: upperheight=2000.0_r_def integer(kind=i_def), parameter :: sten_size = 1 + integer(tik) :: id - if ( subroutine_timers ) call timer('pmsl_alg') + if ( LPROF ) call start_timing( id, 'diags.pmsl' ) pmsl_flag = init_diag(pmsl, 'processed__pmsl') pmsl_unsmooth_flag = init_diag(pmsl_unsmooth, 'processed__pmsl_unsmooth', & @@ -151,7 +152,7 @@ contains end if - if ( subroutine_timers ) call timer('pmsl_alg') + if ( LPROF ) call stop_timing( id, 'diags.pmsl' ) end subroutine pmsl_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/pres_lev_diags_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/pres_lev_diags_alg_mod.x90 index 41d0188eb..0907509b0 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/pres_lev_diags_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/pres_lev_diags_alg_mod.x90 @@ -9,8 +9,8 @@ module pres_lev_diags_alg_mod use field_mod, only: field_type use field_collection_mod, only: field_collection_type - use io_config_mod, only: write_diag, use_xios_io,subroutine_timers - use timer_mod, only: timer + use io_config_mod, only: write_diag, use_xios_io + use timing_mod, only: start_timing, stop_timing, tik, LPROF use constants_mod, only: r_def, i_def, l_def, str_def use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field, & diag_samp => diagnostic_to_be_sampled @@ -82,8 +82,9 @@ contains plev_w_flag, plev_w_clim_flag, plev_omega_clim_flag, & plev_mv_clim_flag, plev_qv_clim_flag, & plev_geopot_flag, plev_geopot_clim_flag, plev_thetaw_flag + integer(tik) :: id - if ( subroutine_timers ) call timer('pres_lev_diags_alg') + if ( LPROF ) call start_timing( id, 'diags.pressure_lev' ) nplev = get_axis_dimension('pressure_levels') allocate(plevs(nplev)) @@ -279,7 +280,7 @@ contains deallocate(plevs) - if ( subroutine_timers ) call timer('pres_lev_diags_alg') + if ( LPROF ) call stop_timing( id, 'diags.pressure_lev' ) end subroutine pres_lev_diags_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/radaer_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/radaer_alg_mod.x90 index d1bf92aa4..d53d66ee8 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/radaer_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/radaer_alg_mod.x90 @@ -16,10 +16,9 @@ module radaer_alg_mod use function_space_collection_mod, & only: function_space_collection use socrates_init_mod, only: n_sw_band, n_lw_band - use io_config_mod, only: subroutine_timers, & - use_xios_io, & + use io_config_mod, only: use_xios_io, & write_diag - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use constants_mod, only: i_def, l_def use radiation_config_mod, & only: n_radstep @@ -205,12 +204,13 @@ contains type( field_type ) :: aaod_ukca_acc_ins type( field_type ) :: aod_ukca_cor_ins type( field_type ) :: aaod_ukca_cor_ins - - if ( subroutine_timers ) call timer('radaer_alg') + integer(tik) :: id_aero, id_diags ! Call on radiation time steps only if (mod(timestep-1_i_def, n_radaer_step*n_radstep) == 0) then + if ( LPROF ) call start_timing( id_aero, 'aerosol.radaer' ) + mesh => theta_in_wth%get_mesh() dz_in_wth => get_dz_at_wtheta(mesh%get_id()) @@ -477,8 +477,12 @@ contains lowest_order_flag=lowest_order_aero_flag ) end if + if ( LPROF ) call stop_timing( id_aero, 'aerosol.radaer' ) + + ! Diagnostic output if ( write_diag .and. use_xios_io ) then + if ( LPROF ) call start_timing( id_diags, 'diags.radaer' ) ! Process radaer diagnostics call output_main_diags_for_radaer( aod_ukca_ait_sol, & @@ -494,12 +498,11 @@ contains aod_ukca_cor_ins, & aaod_ukca_cor_ins ) + if ( LPROF ) call stop_timing( id_diags, 'diags.radaer' ) end if end if - if ( subroutine_timers ) call timer('radaer_alg') - end subroutine radaer_alg end module radaer_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/skeb_main_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/skeb_main_alg_mod.x90 index b49ad7f82..f9e8d6f3c 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/skeb_main_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/skeb_main_alg_mod.x90 @@ -22,8 +22,8 @@ module skeb_main_alg_mod use function_space_collection_mod, only: function_space_collection use mesh_collection_mod, only: mesh_collection ! xios output and timers - use io_config_mod, only: write_diag, use_xios_io, subroutine_timers - use timer_mod, only: timer + use io_config_mod, only: write_diag, use_xios_io + use timing_mod, only: start_timing, stop_timing, tik, LPROF ! initialise diagnostics use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field ! configs @@ -296,8 +296,15 @@ module skeb_main_alg_mod ! Iterators in for loops integer(i_def) :: m, n, n_row, stencil_extent + ! SKEB calculations are performed at cell centres (W3 points). To index the + ! "eta_theta_levels" array correctly at these points, set offset to 1 + integer(kind=i_def), parameter :: lev_offset = 1 + + ! Timing handle + integer(tik) :: id_skeb, id_diags + !!!!!!!!!! END OF VARIABLE DEFINITION, START OF CODE !!!!!!!!!! - if ( subroutine_timers ) call timer("skeb_main_alg") + if ( LPROF ) call start_timing( id_skeb, 'stoch_phys.skeb' ) ! create dissipation functions and psif_hat call rho%copy_field_properties(ndisp) @@ -378,10 +385,10 @@ module skeb_main_alg_mod end if !!!!!! 1.b call stph_fp_main to create forcing pattern for SKEB - call stph_fp_main_alg(skeb_level_bottom-1_i_def, skeb_level_top-1_i_def, & - stph_n_min, stph_n_max, stph_spectral_dim, & - skeb_alpha, skeb_power_law, & - skeb_spectral_coeffc, skeb_spectral_coeffs, & + call stph_fp_main_alg(skeb_level_bottom-1_i_def, skeb_level_top-1_i_def, & + lev_offset, stph_n_min, stph_n_max, stph_spectral_dim, & + skeb_alpha, skeb_power_law, & + skeb_spectral_coeffc, skeb_spectral_coeffs, & fp_skeb) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -458,7 +465,8 @@ module skeb_main_alg_mod skeb_biharm_diss_kernel_type(ndisp, vorticity, divergence, & stencil_extent, dx_at_w2, & skeb_level_bottom, skeb_level_top, & - dt, norm_xi, norm_div) ) + dt, norm_xi, norm_div, & + norm_xi_flag, norm_div_flag) ) if (write_diag .and. use_xios_io) then if (norm_div_flag) & @@ -639,8 +647,12 @@ module skeb_main_alg_mod call invoke( inc_X_plus_Y(du_stph, du_skeb) ) end if + if ( LPROF ) call stop_timing( id_skeb, 'stoch_phys.skeb' ) + ! Add diagnostics to iodef if (write_diag .and. use_xios_io) then + if ( LPROF ) call start_timing( id_diags, 'diags.skeb' ) + call fp_skeb%write_field('stochastic__fp_skeb') call ndisp%write_field('stochastic__ndisp') call cdisp%write_field('stochastic__cdisp') @@ -684,11 +696,9 @@ module skeb_main_alg_mod if (du_tot_skeb_flag) call du_tot_skeb%write_field('stochastic__du_tot_skeb') if (dv_tot_skeb_flag) call dv_tot_skeb%write_field('stochastic__dv_tot_skeb') end if + if ( LPROF ) call stop_timing( id_diags, 'diags.skeb' ) end if ! end if write_diags and use_xios - - if ( subroutine_timers ) call timer("skeb_main_alg") - end subroutine skeb_main_alg end module skeb_main_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/skeb_ndisp_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/skeb_ndisp_alg_mod.x90 index 91a60f790..f8df5cc77 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/skeb_ndisp_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/skeb_ndisp_alg_mod.x90 @@ -20,9 +20,8 @@ module skeb_ndisp_alg_mod ! use collections use function_space_collection_mod, only: function_space_collection ! xios output and timers - use io_config_mod, only: subroutine_timers, write_diag, & - use_xios_io - use timer_mod, only: timer + use io_config_mod, only: write_diag, use_xios_io + use timing_mod, only: start_timing, stop_timing, tik, LPROF ! configs and loging use base_mesh_config_mod, only: geometry, & geometry_spherical @@ -124,13 +123,14 @@ module skeb_ndisp_alg_mod ! Integers integer(kind=i_def) :: i + integer(tik) :: id_skeb, id_stoch, id_diags !!!!!!!!!! END OF VARIABLE DEFINITION, START OF CODE !!!!!!!!!! - if ( subroutine_timers ) call timer("skeb_ndisp_alg") + if ( LPROF ) call start_timing( id_skeb, 'skeb.ndisp' ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! 1) Initialize feilds and operators !! + !! 1) Initialize fields and operators !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Create mesh @@ -242,8 +242,13 @@ module skeb_ndisp_alg_mod call invoke(inc_a_times_X(K_amp, ndisp) ) + if ( LPROF ) call stop_timing( id_skeb, 'skeb.ndisp' ) + if (write_diag .and. use_xios_io) then k_amp = delta_x**4 + ! Stop SKEB timer + if ( LPROF ) call stop_timing( id_stoch, 'stoch_phys.skeb') + if ( LPROF ) call start_timing( id_diags, 'diags.skeb') if (diagnostic_to_be_sampled('stochastic__norm_div')) then call invoke( inc_a_times_X(K_amp, norm_gu) ) call norm_gu%write_field('stochastic__norm_div') @@ -252,9 +257,10 @@ module skeb_ndisp_alg_mod call invoke( inc_a_times_X(K_amp, norm_xi) ) call norm_xi%write_field('stochastic__norm_xi') end if + if ( LPROF ) call stop_timing( id_diags, 'diags.skeb') + ! Restart SKEB timer + if ( LPROF ) call start_timing( id_stoch, 'stoch_phys.skeb') end if - if ( subroutine_timers ) call timer("skeb_ndisp_alg") - end subroutine skeb_ndisp_alg end module skeb_ndisp_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/spectral_gwd_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/spectral_gwd_alg_mod.x90 index a640c58a8..9fa5ed02b 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/spectral_gwd_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/spectral_gwd_alg_mod.x90 @@ -9,8 +9,7 @@ module spectral_gwd_alg_mod use constants_mod, only: i_def use field_mod, only: field_type use field_collection_mod, only: field_collection_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_DEBUG use mesh_mod, only: mesh_type use fs_continuity_mod, only: W3, Wtheta @@ -87,8 +86,9 @@ contains type( mesh_type ), pointer :: mesh => null() type( mesh_type ), pointer :: twod_mesh => null() integer( kind=i_def ) :: ncells + integer( tik ) :: id - if ( subroutine_timers ) call timer("spectral_gwd_alg") + if ( LPROF ) call start_timing( id, 'spectral_gwd' ) call log_event( 'slow_physics: Running spectral gravity wave drag', LOG_LEVEL_DEBUG ) @@ -146,7 +146,7 @@ contains call um_sizes_init(1_i_def) - if ( subroutine_timers ) call timer("spectral_gwd_alg") + if ( LPROF ) call stop_timing( id, 'spectral_gwd' ) if (write_diag .and. use_xios_io) then diff --git a/interfaces/physics_schemes_interface/source/algorithm/spt_main_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/spt_main_alg_mod.x90 index 0f61d1267..abacd9da7 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/spt_main_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/spt_main_alg_mod.x90 @@ -8,7 +8,7 @@ module spt_main_alg_mod - use constants_mod, only: r_def, i_def, l_def + use constants_mod, only: r_def, i_def, l_def, r_second use fs_continuity_mod, only: W0, Wtheta ! define types use clock_mod, only: clock_type @@ -16,9 +16,8 @@ module spt_main_alg_mod use field_collection_mod, only: field_collection_type use mesh_mod, only: mesh_type ! for IO and timers - use io_config_mod, only: write_diag, use_xios_io, & - subroutine_timers - use timer_mod, only: timer + use io_config_mod, only: write_diag, use_xios_io + use timing_mod, only: start_timing, stop_timing, tik, LPROF ! load modules to set up the W0 space for 1-2-1 filtering ! wtheta -> w0 bottom DoF -> wtheta use function_space_collection_mod, only: function_space_collection @@ -79,32 +78,39 @@ module spt_main_alg_mod microphysics_fields, radiation_fields, & derived_fields, orography_fields, clock) + ! Timestepping parameters + use timestepping_config_mod, only: dt_timestep => dt + ! SPT parameters - use stochastic_physics_config_mod, only: & + use stochastic_physics_config_mod, only: & ! Switches to use different ! parametrizations - spt_use_radiation, & - spt_use_microphysics,& - spt_use_convection, & + spt_use_radiation, & + spt_use_microphysics, & + spt_use_convection, & ! Std dev of each param. - spt_stddev_radiation, & - spt_stddev_microphysics, & - spt_stddev_convection, & + spt_stddev_radiation, & + spt_stddev_microphysics, & + spt_stddev_convection, & ! CFL criteria - spt_convection_cfl_limit, & + spt_convection_cfl_limit, & ! conservation - spt_mse_conservation, & - spt_moisture_conservation, & + spt_mse_conservation, & + spt_moisture_conservation, & ! 1-2-1 smoothing - spt_n_smoothing_iters, & + spt_n_smoothing_iters, & ! Add increments - spt_add_increments, & + spt_add_increments, & ! SPT levels - spt_level_bottom, & - spt_level_top, & + spt_level_bottom, & + spt_level_top, & + spt_level_begin_tapering_bottom, & + spt_level_begin_tapering_top, & + spt_orog_forcing_pattern_thresh, & + spt_stddev_orog_thres, & ! Stoch Phy wavenumbers - stph_n_max, & - stph_spectral_dim, & + stph_n_max, & + stph_spectral_dim, & ! power law spt_decorrelation_time @@ -223,7 +229,19 @@ module spt_main_alg_mod ! iterators in for loops integer(i_def) :: n,n_row, m - if ( subroutine_timers ) call timer("spt_main_alg") + ! SPT calculations are performed at theta-levels (Wtheta points). To index the + ! "eta_theta_levels" array correctly at these points, set offset to 0 + integer(kind=i_def), parameter :: lev_offset = 0 + + ! Timestepping_config_mod scalar (for PSyclone to know data type) + real(kind=r_second) :: timestepping_config_mod_dt + + ! Timing handle + integer(tik) :: id_alg, id_diags + + if ( LPROF ) call start_timing( id_alg, 'stoch_phys.spt' ) + + timestepping_config_mod_dt = dt_timestep !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! 1) Create Forcing pattern || @@ -284,10 +302,10 @@ module spt_main_alg_mod call invoke( setval_c(fp_spt, 0.0_r_def)) ! Create forcing pattern for SPT - call stph_fp_main_alg(spt_level_bottom, spt_level_top, & - 1, stph_n_max, stph_spectral_dim, & - spt_alpha, spt_power_law, & - spt_spectral_coeffc, spt_spectral_coeffs, & + call stph_fp_main_alg(spt_level_bottom, spt_level_top, lev_offset, & + 1, stph_n_max, stph_spectral_dim, & + spt_alpha, spt_power_law, & + spt_spectral_coeffc, spt_spectral_coeffs, & fp_spt) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -362,10 +380,12 @@ module spt_main_alg_mod if (spt_convection_cfl_limit) then if (.not. spt_mse_conservation) then call invoke(spt_convection_cfl_limit_cap_kernel_type(dt_conv_cfl, massflux_up, & - fp_spt, pressure)) + fp_spt, pressure, spt_level_bottom, & + spt_level_top, timestepping_config_mod_dt)) end if call invoke(spt_convection_cfl_limit_cap_kernel_type(dmv_conv_cfl, massflux_up, & - fp_spt, pressure)) + fp_spt, pressure, spt_level_bottom, & + spt_level_top, timestepping_config_mod_dt)) end if ! Apply tendencies to dX_spt, conver dt to theta @@ -393,18 +413,28 @@ module spt_main_alg_mod !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (.not. spt_mse_conservation) then - call invoke(spt_levels_cap_kernel_type(dtheta_spt)) + call invoke(spt_levels_cap_kernel_type(dtheta_spt, spt_level_bottom, & + spt_level_top, spt_level_begin_tapering_bottom, & + spt_level_begin_tapering_top)) end if - call invoke(spt_levels_cap_kernel_type(dmv_spt)) + call invoke(spt_levels_cap_kernel_type(dmv_spt, spt_level_bottom, & + spt_level_top, spt_level_begin_tapering_bottom, & + spt_level_begin_tapering_top)) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! 5) Apply orographic capping !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (.not. spt_mse_conservation) then - call invoke(spt_orog_cap_kernel_type(dtheta_spt,fp_spt,sd_orog)) + call invoke(spt_orog_cap_kernel_type(dtheta_spt,fp_spt,sd_orog, & + spt_level_bottom, spt_level_top, & + spt_orog_forcing_pattern_thresh, & + spt_stddev_orog_thres)) end if - call invoke(spt_orog_cap_kernel_type(dmv_spt,fp_spt,sd_orog)) + call invoke(spt_orog_cap_kernel_type(dmv_spt,fp_spt,sd_orog, & + spt_level_bottom, spt_level_top, & + spt_orog_forcing_pattern_thresh, & + spt_stddev_orog_thres)) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! 6) Remove points where perturbations cause super-saturation !! @@ -462,7 +492,9 @@ module spt_main_alg_mod if (spt_moisture_conservation) then mesh => dtheta%get_mesh() dz_wth => get_dz_at_wtheta(mesh%get_id()) - call invoke(spt_moisture_conservation_kernel_type(dmv_spt,mv,dz_wth,rho_in_wth)) + call invoke(spt_moisture_conservation_kernel_type(dmv_spt,mv,dz_wth, & + rho_in_wth,spt_level_bottom, & + spt_level_top)) end if ! Apply MSE conservation in the column if requested @@ -483,14 +515,16 @@ module spt_main_alg_mod inc_X_plus_Y(dmv_stph, dmv_spt) ) end if + if ( LPROF ) call stop_timing( id_alg, 'stoch_phys.spt' ) + ! Write fields to diagnostics if requested if (write_diag .and. use_xios_io) then + if ( LPROF ) call start_timing( id_diags, 'diags.stoch_phys' ) call fp_spt%write_field('stochastic__fp_spt') call dtheta_spt%write_field('stochastic__dtheta_spt') call dmv_spt%write_field('stochastic__dmv_spt') + if ( LPROF ) call stop_timing( id_diags, 'diags.stoch_phys' ) end if - if ( subroutine_timers ) call timer("spt_main_alg") - end subroutine spt_main_alg end module spt_main_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/stph_fp_main_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/stph_fp_main_alg_mod.x90 index c0a1f2ff1..a6abf14be 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/stph_fp_main_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/stph_fp_main_alg_mod.x90 @@ -14,8 +14,7 @@ module stph_fp_main_alg_mod use fs_continuity_mod, only: W3 use mesh_mod, only: mesh_type use mesh_collection_mod, only: mesh_collection - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use level_heights_mod, only: eta_theta_levels use extrusion_config_mod, only: domain_height @@ -47,6 +46,12 @@ module stph_fp_main_alg_mod !>@param[in] level_bottom Bottom level of the stochastic scheme !>@param[in] level_top Top level of the stochastic scheme + !>@param[in] level_offset Level offset. This routine can be + !! applied at W3 and Wtheta points, + !! but both implementations index + !! from the same "eta_theta_levels" + !! array, so need an offset to index + !! correctly. Set 0 Wtheta, 1 for W3 !>@param[in] wavenumber_min Minimum wavenumber applied to build the FP !>@param[in] wavenumber_max Maximum wavenumber applied to build the FP !>@param[in] spectral_dim Dimension of spectral coeffients arrays @@ -56,10 +61,10 @@ module stph_fp_main_alg_mod !>@param[in,out] spectral_coeffs Imaginary Spectral coefficients !>@param[i,out] fp Forcing pattern - subroutine stph_fp_main_alg(level_bottom, level_top, & - wavenumber_min, wavenumber_max, & - spectral_dim, alpha, power_law, & - spectral_coeffc, spectral_coeffs, & + subroutine stph_fp_main_alg(level_bottom, level_top, level_offset, & + wavenumber_min, wavenumber_max, & + spectral_dim, alpha, power_law, & + spectral_coeffc, spectral_coeffs, & fp) ! TO DO after PSyclone ticket 1312 @@ -79,8 +84,8 @@ module stph_fp_main_alg_mod !!!! Arguments ! Scalars with scheme levels, wavenumbers and spectral dimensions - integer(kind=i_def), intent(in) :: level_bottom, level_top, & - wavenumber_min, wavenumber_max, & + integer(kind=i_def), intent(in) :: level_bottom, level_top, level_offset, & + wavenumber_min, wavenumber_max, & spectral_dim ! spectral coefficients power law and decorrelation @@ -117,7 +122,10 @@ module stph_fp_main_alg_mod integer(i_def) :: fs_id ! iterators in for loops integer(kind=i_def) :: n, m, n_row, k - if ( subroutine_timers ) call timer("stph_fp_main_alg") + ! Timing handle + integer(tik) :: id + + if ( LPROF ) call start_timing( id, 'spt.forcing_pattern' ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! 1) Apply the First Auto-regressive process (1AR) !! @@ -151,12 +159,13 @@ module stph_fp_main_alg_mod my_phi_stph = ATAN2(spectral_coeffs(n_row+m), & spectral_coeffc(n_row+m)) ! Max shift ranges from 0 <-> pi for wavenos 1 <-> wavenumber_max - my_phishft_stph = (wavenumber_max - max(n,m)) * pi / (wavenumber_max-1) + my_phishft_stph = (wavenumber_max - max(n,m)) * pi & + / (wavenumber_max - wavenumber_min) do k = level_bottom, level_top ! Apply vertical scaling Level 1 = no change -> 12km Level = max change (=pi) - kr = (domain_height*eta_theta_levels(k))/12.0e3_r_def + kr = (domain_height*eta_theta_levels(k + level_offset))/12.0e3_r_def ! Create coeff with phase shift coeffc_phase(k, n_row+m) = my_coeff_rad * cos(my_phi_stph + & @@ -203,7 +212,7 @@ module stph_fp_main_alg_mod level_bottom, level_top, & wavenumber_min, wavenumber_max) - if ( subroutine_timers ) call timer("stph_fp_main_alg") + if ( LPROF ) call stop_timing( id, 'spt.forcing_pattern' ) end subroutine stph_fp_main_alg diff --git a/interfaces/physics_schemes_interface/source/algorithm/stph_main_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/stph_main_alg_mod.x90 index 9d4cb3631..9a7a39c7c 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/stph_main_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/stph_main_alg_mod.x90 @@ -14,9 +14,7 @@ module stph_main_alg_mod use clock_mod, only: clock_type use field_collection_mod, only: field_collection_type ! xios output and timers - use io_config_mod, only: write_diag, use_xios_io, & - subroutine_timers - use timer_mod, only: timer + use io_config_mod, only: write_diag, use_xios_io implicit none @@ -78,8 +76,6 @@ module stph_main_alg_mod ! classes class(clock_type), intent(in) :: clock - if ( subroutine_timers ) call timer("stph_main_alg") - call invoke(setval_c(du_stph, 0.0_r_def), & setval_c(dtheta_stph, 0.0_r_def), & setval_c(dmv_stph, 0.0_r_def)) @@ -97,7 +93,5 @@ module stph_main_alg_mod call skeb_main_alg(du_stph, rho, u, convection_fields, derived_fields,clock) end if - if ( subroutine_timers ) call timer("stph_main_alg") - end subroutine stph_main_alg end module stph_main_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/strat_aerosol_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/strat_aerosol_alg_mod.x90 index 277d9b22e..7dbdceeb4 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/strat_aerosol_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/strat_aerosol_alg_mod.x90 @@ -12,8 +12,7 @@ use field_mod, only: field_type use integer_field_mod, only: integer_field_type use field_collection_mod, only: field_collection_type use strat_aerosol_kernel_mod, only: strat_aerosol_kernel_type -use io_config_mod, only: subroutine_timers -use timer_mod, only: timer +use timing_mod, only: start_timing, stop_timing, tik, LPROF use function_space_mod, only: function_space_type use function_space_collection_mod, & only: function_space_collection @@ -47,8 +46,9 @@ subroutine strat_aerosol_alg( aerosol_fields, trop_level, exner ) type( field_type ) :: sulphuric_aero type(function_space_type), pointer :: wth_aero => null() type(mesh_type), pointer :: aerosol_mesh => null() - - if ( subroutine_timers ) call timer("strat_aerosol_alg") + integer(tik) :: id + + if ( LPROF ) call start_timing( id, 'aerosol.stratosphere' ) if (coarse_rad_aerosol) then ! Initialise potentially coarse aerosol field @@ -63,7 +63,7 @@ subroutine strat_aerosol_alg( aerosol_fields, trop_level, exner ) call invoke( strat_aerosol_kernel_type( sulphuric, trop_level, exner ) ) end if - if ( subroutine_timers ) call timer("strat_aerosol_alg") + if ( LPROF ) call stop_timing( id, 'aerosol.stratosphere' ) end subroutine strat_aerosol_alg end module strat_aerosol_alg_mod diff --git a/interfaces/physics_schemes_interface/source/algorithm/surf_temp_forcing_alg_mod.x90 b/interfaces/physics_schemes_interface/source/algorithm/surf_temp_forcing_alg_mod.x90 index 7cdb2be82..f140e5f15 100644 --- a/interfaces/physics_schemes_interface/source/algorithm/surf_temp_forcing_alg_mod.x90 +++ b/interfaces/physics_schemes_interface/source/algorithm/surf_temp_forcing_alg_mod.x90 @@ -9,12 +9,11 @@ module surf_temp_forcing_alg_mod use field_mod, only: field_type use field_collection_mod, only: field_collection_type -use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_DEBUG, & LOG_LEVEL_WARNING, & LOG_LEVEL_ERROR -use timer_mod, only: timer +use timing_mod, only: start_timing, stop_timing, tik, LPROF use specified_surface_config_mod, only: surf_temp_forcing, & surf_temp_forcing_none, & surf_temp_forcing_int_flux @@ -47,8 +46,9 @@ contains type( field_type ), pointer :: sw_up_tile type( field_type ), pointer :: internal_flux type( field_type ), pointer :: tile_temperature + integer( tik ) :: id - if ( subroutine_timers ) call timer('surf_temp_forcing_alg') + if ( LPROF ) call start_timing( id, 'surf_temp_forcing' ) if (surf_temp_forcing /= surf_temp_forcing_none) then @@ -82,7 +82,7 @@ contains end select end if - if ( subroutine_timers ) call timer('surf_temp_forcing_alg') + if ( LPROF ) call stop_timing( id, 'surf_temp_forcing' ) end subroutine surf_temp_forcing_alg end module surf_temp_forcing_alg_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/bl_exp_diags_mod.f90 b/interfaces/physics_schemes_interface/source/diagnostics/bl_exp_diags_mod.f90 index 610bfd7c8..23051799b 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/bl_exp_diags_mod.f90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/bl_exp_diags_mod.f90 @@ -10,8 +10,7 @@ module bl_exp_diags_mod use constants_mod, only: l_def use field_mod, only: field_type use integer_field_mod, only: integer_field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field implicit none @@ -35,13 +34,14 @@ subroutine initialise_diags_for_bl_exp(zht, oblen) type( field_type ), intent(inout) :: zht type( field_type ), intent(inout) :: oblen + integer( tik ) :: id - if ( subroutine_timers ) call timer("bl_exp_diags") + if ( LPROF ) call start_timing( id, 'diags.bl_exp' ) zht_flag = init_diag(zht, 'turbulence__zht') oblen_flag = init_diag(oblen, 'turbulence__oblen') - if ( subroutine_timers ) call timer("bl_exp_diags") + if ( LPROF ) call stop_timing( id, 'diags.bl_exp' ) end subroutine initialise_diags_for_bl_exp @@ -90,9 +90,9 @@ subroutine output_diags_for_bl_exp(ntml, cumulus, bl_type_ind, & ent_zrzi_dsc, oblen, bl_weight_1dbl type(integer_field_type), intent(in) :: level_ent, level_ent_dsc, ntml, & cumulus, bl_type_ind + integer( tik ) :: id - - if ( subroutine_timers ) call timer("bl_exp_diags") + if ( LPROF ) call start_timing( id, 'diags.bl_exp' ) ! Prognostic fields from turbulence collection call ntml%write_field('turbulence__ntml') @@ -121,7 +121,7 @@ subroutine output_diags_for_bl_exp(ntml, cumulus, bl_type_ind, & if (zht_flag) call zht%write_field() if (oblen_flag) call oblen%write_field() - if ( subroutine_timers ) call timer("bl_exp_diags") + if ( LPROF ) call stop_timing( id, 'diags.bl_exp' ) end subroutine output_diags_for_bl_exp end module bl_exp_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/bl_imp_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/bl_imp_diags_mod.x90 index bc09f3632..bf02ad998 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/bl_imp_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/bl_imp_diags_mod.x90 @@ -11,8 +11,7 @@ module bl_imp_diags_mod use field_mod, only: field_type use bl_extra_diags_kernel_mod, only: bl_extra_diags_kernel_type use physics_mappings_alg_mod, only: map_physics_winds - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field, & samp_diag => diagnostic_to_be_sampled @@ -110,8 +109,9 @@ contains ! are mapped from tau_w2 by map_physics_winds (to w3) in bl_imp_alg type( field_type ), intent(inout) :: taux, tauy type( field_type ), intent(inout) :: ustar_implicit + integer( tik ) :: id - if ( subroutine_timers ) call timer("bl_imp_diags") + if ( LPROF ) call start_timing( id, 'diags.bl_imp' ) ! Genuine turbulence diagnostics ! 3D fields in wtheta space @@ -147,7 +147,7 @@ contains tauy_flag = init_diag(tauy, 'turbulence__tauy', activate=.true.) ustar_implicit_flag = init_diag(ustar_implicit, 'surface__ustar_implicit', activate=.true.) - if ( subroutine_timers ) call timer("bl_imp_diags") + if ( LPROF ) call stop_timing( id, 'diags.bl_imp' ) end subroutine initialise_diags_for_bl_imp @@ -282,8 +282,9 @@ contains type( field_type ) :: pseudotaux, pseudotauy logical( l_def ) :: ignore + integer( tik ) :: id - if ( subroutine_timers ) call timer("bl_imp_diags") + if ( LPROF ) call start_timing( id, 'diags.bl_imp' ) ! Output prognostic fields if (samp_diag('aerosol__murk')) call murk%write_field('aerosol__murk') @@ -449,7 +450,7 @@ contains if (dew_point_land_flag) call dew_point_land%write_field() end if - if ( subroutine_timers ) call timer("bl_imp_diags") + if ( LPROF ) call stop_timing( id, 'diags.bl_imp' ) end subroutine output_diags_for_bl_imp end module bl_imp_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/casim_diagnostics_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/casim_diagnostics_mod.x90 index 1ab0e890d..cd3a392e2 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/casim_diagnostics_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/casim_diagnostics_mod.x90 @@ -9,8 +9,7 @@ module casim_diagnostics_mod use constants_mod, only: l_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field @@ -54,8 +53,9 @@ contains type( field_type ), intent(inout) :: superc_liq type( field_type ), intent(inout) :: superc_rain type( field_type ), intent(inout) :: ls_graup_3d + integer( tik ) :: id - if ( subroutine_timers ) call timer("casim_diagnostics") + if ( LPROF ) call start_timing( id, 'diags.casim' ) refl_tot_flag = init_diag(refl_tot, 'microphysics__refl_tot') refl_1km_flag = init_diag(refl_1km, 'microphysics__refl_1km') @@ -63,7 +63,7 @@ contains superc_rain_flag = init_diag(superc_rain, 'microphysics__superc_rain') ls_graup_3d_flag = init_diag(ls_graup_3d, 'microphysics__ls_graup_3d') - if ( subroutine_timers ) call timer("casim_diagnostics") + if ( LPROF ) call stop_timing( id, 'diags.casim' ) end subroutine initialise_diags_for_casim @@ -95,11 +95,11 @@ contains superc_liq, superc_rain type ( field_type ) :: dt_mphys - + integer(tik) :: id !-------------------------------------- ! End of declarations !-------------------------------------- - if ( subroutine_timers ) call timer ("casim_diagnostics") + if ( LPROF ) call start_timing( id, 'diags.casim' ) !---------------------------------------------------- @@ -170,7 +170,7 @@ contains call ns_mphys%write_field('casim__ns_mphys') call ng_mphys%write_field('casim__ng_mphys') - if ( subroutine_timers ) call timer ("casim_diagnostics") + if ( LPROF ) call stop_timing( id, 'diags.casim' ) end subroutine output_diags_for_casim diff --git a/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90 index 295a1425d..6b6eb9a40 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/cld_diags_mod.x90 @@ -16,8 +16,7 @@ module cld_diags_mod use field_collection_mod, only: field_collection_type use field_collection_iterator_mod, & only: field_collection_iterator_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use sci_geometric_constants_mod, & only: get_height_fv use cloud_config_mod, only: filter_optical_depth, opt_depth_thresh @@ -64,8 +63,9 @@ contains ! Diagnostic fields to initialise type( field_type ), intent(inout) :: sskew_bm, svar_bm, svar_tb logical(l_def), intent(in) :: call_b4_conv + integer(tik) :: id - if ( subroutine_timers ) call timer("cld_diags") + if ( LPROF ) call start_timing( id, 'diags.cloud' ) if (call_b4_conv) then ! No diagnostics output in mid-timestep call @@ -79,7 +79,7 @@ contains svar_tb_flag = init_diag(svar_tb, 'cloud__svar_tb') end if - if ( subroutine_timers ) call timer("cld_diags") + if ( LPROF ) call stop_timing( id, 'diags.cloud' ) end subroutine initialise_diags_for_cld @@ -146,8 +146,9 @@ contains class( field_parent_type ), pointer :: field_ptr => null() character(str_def) :: name logical( l_def ) :: ignore + integer( tik ) :: id - if ( subroutine_timers ) call timer("cld_diags") + if ( LPROF ) call start_timing( id, 'diags.cloud' ) ! 2D fields cld_amount_max_flag = init_diag(cld_amount_max, 'cloud__cloud_amount_max') @@ -366,7 +367,7 @@ contains if (cloud_fraction_below_1000feet_asl_flag) call & cloud_fraction_below_1000feet_asl%write_field() - if ( subroutine_timers ) call timer("cld_diags") + if ( LPROF ) call stop_timing( id, 'diags.cloud' ) end subroutine output_diags_for_cld end module cld_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/comorph_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/comorph_diags_mod.x90 index 29a6a8af8..14aee7951 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/comorph_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/comorph_diags_mod.x90 @@ -9,8 +9,7 @@ module comorph_diags_mod use constants_mod, only: l_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only : init_diag & => init_diagnostic_field @@ -70,8 +69,9 @@ contains detrain_up, & detrain_down, & massflux_up_half + integer(tik) :: id - if ( subroutine_timers ) call timer("comorph_diags") + if ( LPROF ) call start_timing( id, 'diags.comorph' ) ! Convective diagnostics - 2d lowest_cv_base_flag = init_diag(lowest_cv_base, 'convection__lowest_cv_base') @@ -105,7 +105,7 @@ contains massflux_up_half_flag = init_diag(massflux_up_half, 'convection__massflux_up_half') - if ( subroutine_timers ) call timer("comorph_diags") + if ( LPROF ) call stop_timing( id, 'diags.comorph' ) end subroutine initialise_diags_for_comorph @@ -183,8 +183,9 @@ contains detrain_up, & detrain_down, & massflux_up_half + integer(tik) :: id - if ( subroutine_timers ) call timer("comorph_diags") + if ( LPROF ) call start_timing( id, 'diags.comorph' ) ! Prognostic fields call cca%write_field('convection__cca') @@ -230,7 +231,7 @@ contains if (detrain_down_flag) call detrain_down%write_field() if (massflux_up_half_flag) call massflux_up_half%write_field() - if ( subroutine_timers ) call timer("comorph_diags") + if ( LPROF ) call stop_timing( id, 'diags.comorph' ) end subroutine output_diags_for_comorph end module comorph_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/conv_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/conv_diags_mod.x90 index 28b637aa0..705a22118 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/conv_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/conv_diags_mod.x90 @@ -9,8 +9,7 @@ module conv_diags_mod use constants_mod, only: l_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only : init_diag & => init_diagnostic_field @@ -159,8 +158,9 @@ contains dmv_conv_noshal logical(l_def) :: ignore + integer(tik) :: id - if ( subroutine_timers ) call timer("conv_diags") + if ( LPROF ) call start_timing( id, 'diags.conv' ) ! Convective diagnostics - 2d deep_in_col_flag = init_diag(deep_in_col, 'convection__deep_in_col') @@ -302,7 +302,7 @@ contains call invoke( setval_c(shallow_in_col, 0.0_r_def) ) end if - if ( subroutine_timers ) call timer("conv_diags") + if ( LPROF ) call stop_timing( id, 'diags.conv' ) end subroutine initialise_diags_for_conv @@ -434,8 +434,9 @@ contains cca_unadjusted, & dth_conv_noshal, & dmv_conv_noshal + integer( tik ) :: id - if ( subroutine_timers ) call timer("conv_diags") + if ( LPROF ) call start_timing( id, 'diags.conv' ) ! Prognostic fields call cca%write_field('convection__cca') @@ -507,7 +508,7 @@ contains if (dth_conv_noshal_flag) call dth_conv_noshal%write_field() if (dmv_conv_noshal_flag) call dmv_conv_noshal%write_field() - if ( subroutine_timers ) call timer("conv_diags") + if ( LPROF ) call stop_timing( id, 'diags.conv' ) end subroutine output_diags_for_conv end module conv_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/electric_main_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/electric_main_diags_mod.x90 index f40ea91a1..1427d080b 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/electric_main_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/electric_main_diags_mod.x90 @@ -10,8 +10,7 @@ module electric_main_diags_mod use constants_mod, only: l_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field implicit none @@ -43,11 +42,12 @@ contains type( field_type ), intent(inout) :: fr1_mc type( field_type ), intent(inout) :: fr2_mc type( field_type ), intent(inout) :: storm_field + integer( tik ) :: id !---------------------------------------------------- ! End of declarations; start of subroutine execution !---------------------------------------------------- - if ( subroutine_timers ) call timer("electric_diags") + if ( LPROF ) call start_timing( id, 'diags.electric' ) gwp_flag = init_diag(gwp, 'electric__gwp') tiwp_flag = init_diag(tiwp, 'electric__tiwp') @@ -56,7 +56,7 @@ contains fr2_mc_flag = init_diag(fr2_mc, 'electric__total_column_ice_flash_rate') storm_field_flag = init_diag(storm_field, 'electric__storm_field_indicator') - if ( subroutine_timers ) call timer("electric_diags") + if ( LPROF ) call stop_timing( id, 'diags.electric' ) end subroutine initialise_main_diags_for_electric @@ -85,10 +85,12 @@ contains ! Prognostic field to be output type( field_type), intent(in) :: flash_potential + integer(tik) :: id + !---------------------------------------------------- ! End of declarations; start of subroutine execution !---------------------------------------------------- - if ( subroutine_timers ) call timer("electric_diags") + if ( LPROF ) call start_timing( id, 'diags.electric' ) call flash_potential%write_field('electric__flash_potential') call num_flashes%write_field('electric__num_lightning_flashes') @@ -100,6 +102,6 @@ contains if (fr2_mc_flag) call fr2_mc%write_field() if (storm_field_flag) call storm_field%write_field() - if ( subroutine_timers ) call timer("electric_diags") + if ( LPROF ) call stop_timing( id, 'diags.electric' ) end subroutine output_main_diags_for_electric end module electric_main_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/mphys_diagnostics_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/mphys_diagnostics_mod.x90 index ef0c0386f..7f4f66391 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/mphys_diagnostics_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/mphys_diagnostics_mod.x90 @@ -9,8 +9,7 @@ module mphys_diagnostics_mod use constants_mod, only: l_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field @@ -60,8 +59,9 @@ contains type( field_type ), intent(inout) :: sfsnow type( field_type ), intent(inout) :: refl_tot type( field_type ), intent(inout) :: refl_1km + integer( tik ) :: id - if ( subroutine_timers ) call timer("mphys_diagnostics") + if ( LPROF ) call start_timing( id, 'diags.mphys' ) superc_liq_flag = init_diag(superc_liq, 'microphysics__superc_liq') superc_rain_flag = init_diag(superc_rain, 'microphysics__superc_rain') @@ -71,7 +71,7 @@ contains refl_tot_flag = init_diag(refl_tot, 'microphysics__refl_tot') refl_1km_flag = init_diag(refl_1km, 'microphysics__refl_1km') - if ( subroutine_timers ) call timer("mphys_diagnostics") + if ( LPROF ) call stop_timing( id, 'diags.mphys' ) end subroutine @@ -125,11 +125,12 @@ contains refl_1km type ( field_type ) :: dt_mphys + integer( tik ) :: id !-------------------------------------- ! End of declarations !-------------------------------------- - if ( subroutine_timers ) call timer ("mphys_diagnostics") + if ( LPROF ) call start_timing( id, 'diags.mphys' ) !-------------------------------------- ! Output locally computed 3D diagnostics @@ -194,7 +195,7 @@ contains call tnuc%write_field('microphysics__tnuc') - if ( subroutine_timers ) call timer ("mphys_diagnostics") + if ( LPROF ) call stop_timing( id, 'diags.mphys' ) end subroutine output_diags_for_mphys diff --git a/interfaces/physics_schemes_interface/source/diagnostics/orographic_drag_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/orographic_drag_diags_mod.x90 index 943e49d6f..5bb96cac4 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/orographic_drag_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/orographic_drag_diags_mod.x90 @@ -9,8 +9,7 @@ module orographic_drag_diags_mod use constants_mod, only: l_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field @@ -48,8 +47,9 @@ contains type( field_type ), intent(inout) :: & taux_orog_blk, tauy_orog_blk, & taux_orog_gwd, tauy_orog_gwd + integer( tik ) :: id - if ( subroutine_timers ) call timer("orographic_drag_diags") + if ( LPROF ) call start_timing( id, 'diags.orog_gwd' ) ! 3D fields in wtheta space taux_orog_blk_flag = init_diag(taux_orog_blk, 'orographic_drag__taux_orog_blk') @@ -61,7 +61,7 @@ contains tauy_orog_gwd_flag = init_diag(tauy_orog_gwd, 'orographic_drag__tauy_orog_gwd') if (tauy_orog_gwd_flag) call invoke( setval_c(tauy_orog_gwd, 0.0_r_def) ) - if ( subroutine_timers ) call timer("orographic_drag_diags") + if ( LPROF ) call stop_timing( id, 'diags.orog_gwd' ) end subroutine initialise_diags_for_orographic_drag @@ -79,8 +79,9 @@ contains dtheta_orographic_drag, du_orog_blk, dv_orog_blk, dtemp_orog_blk, & du_orog_gwd, dv_orog_gwd, dtemp_orog_gwd, & taux_orog_blk, tauy_orog_blk, taux_orog_gwd, tauy_orog_gwd + integer( tik ) :: id - if ( subroutine_timers ) call timer("orographic_drag_diags") + if ( LPROF ) call start_timing( id, 'diags.orog_gwd' ) ! Prognostic fields call du_orographic_drag%write_field('orographic_drag__du_orographic_drag') @@ -100,7 +101,7 @@ contains if (taux_orog_gwd_flag) call taux_orog_gwd%write_field() if (tauy_orog_gwd_flag) call tauy_orog_gwd%write_field() - if ( subroutine_timers ) call timer("orographic_drag_diags") + if ( LPROF ) call stop_timing( id, 'diags.orog_gwd' ) end subroutine output_diags_for_orographic_drag end module orographic_drag_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/radaer_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/radaer_diags_mod.x90 index f1afe99a3..85188878e 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/radaer_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/radaer_diags_mod.x90 @@ -11,8 +11,7 @@ module radaer_main_diags_mod use constants_mod, only: l_def use integer_field_mod, only: integer_field_type use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field use mesh_mod, only: mesh_type @@ -77,12 +76,13 @@ contains type( integer_field_type ), intent(in) :: trop_level type(mesh_type), pointer :: mesh => null() + integer( tik ) :: id !---------------------------------------------------- ! End of declarations; start of subroutine execution !---------------------------------------------------- - if ( subroutine_timers ) call timer("radaer_diags") + if ( LPROF ) call start_timing( id, 'diags.radaer' ) ! Get 2D mesh from trop level field mesh => trop_level%get_mesh() @@ -183,7 +183,7 @@ contains call invoke(setval_c( aaod_ukca_cor_ins, 0.0_r_def)) end if - if ( subroutine_timers ) call timer("radaer_diags") + if ( LPROF ) call stop_timing( id, 'diags.radaer' ) end subroutine initialise_main_diags_for_radaer @@ -222,11 +222,11 @@ contains aod_ukca_ait_ins, aaod_ukca_ait_ins, & aod_ukca_acc_ins, aaod_ukca_acc_ins, & aod_ukca_cor_ins, aaod_ukca_cor_ins - + integer( tik ) :: id !---------------------------------------------------- ! End of declarations; start of subroutine execution !---------------------------------------------------- - if ( subroutine_timers ) call timer("radaer_diags") + if ( LPROF ) call start_timing( id, 'diags.radaer' ) if (aod_ukca_ait_sol_flag) call aod_ukca_ait_sol%write_field() if (aaod_ukca_ait_sol_flag) call aaod_ukca_ait_sol%write_field() @@ -241,6 +241,6 @@ contains if (aod_ukca_cor_ins_flag) call aod_ukca_cor_ins%write_field() if (aaod_ukca_cor_ins_flag) call aaod_ukca_cor_ins%write_field() - if ( subroutine_timers ) call timer("radaer_diags") + if ( LPROF ) call stop_timing( id, 'diags.radaer' ) end subroutine output_main_diags_for_radaer -end module radaer_main_diags_mod \ No newline at end of file +end module radaer_main_diags_mod diff --git a/interfaces/physics_schemes_interface/source/diagnostics/spectral_gwd_diags_mod.x90 b/interfaces/physics_schemes_interface/source/diagnostics/spectral_gwd_diags_mod.x90 index 4b44eb884..030127feb 100644 --- a/interfaces/physics_schemes_interface/source/diagnostics/spectral_gwd_diags_mod.x90 +++ b/interfaces/physics_schemes_interface/source/diagnostics/spectral_gwd_diags_mod.x90 @@ -9,8 +9,7 @@ module spectral_gwd_diags_mod use constants_mod, only: l_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only : init_diag => init_diagnostic_field @@ -47,8 +46,9 @@ contains type( field_type ), intent(inout) :: & tau_east_spectral_gwd, tau_south_spectral_gwd, & tau_west_spectral_gwd, tau_north_spectral_gwd + integer( tik ) :: id - if ( subroutine_timers ) call timer("spectral_gwd_diags") + if ( LPROF ) call start_timing( id, 'diags.spectral_gwd' ) ! 3D fields in wtheta space tau_east_spectral_gwd_flag = init_diag(tau_east_spectral_gwd, 'spectral_gwd__tau_east_spectral_gwd') @@ -56,7 +56,7 @@ contains tau_west_spectral_gwd_flag = init_diag(tau_west_spectral_gwd, 'spectral_gwd__tau_west_spectral_gwd') tau_north_spectral_gwd_flag = init_diag(tau_north_spectral_gwd, 'spectral_gwd__tau_north_spectral_gwd') - if ( subroutine_timers ) call timer("spectral_gwd_diags") + if ( LPROF ) call stop_timing( id, 'diags.spectral_gwd' ) end subroutine initialise_diags_for_spectral_gwd @@ -74,8 +74,9 @@ contains dtheta_spectral_gwd, tau_east_spectral_gwd, & tau_south_spectral_gwd, tau_west_spectral_gwd, & tau_north_spectral_gwd + integer( tik ) :: id - if ( subroutine_timers ) call timer("spectral_gwd_diags") + if ( LPROF ) call start_timing( id, 'diags.spectral_gwd' ) ! Prognostic fields call du_spectral_gwd%write_field('spectral_gwd__du_spectral_gwd') @@ -89,7 +90,7 @@ contains if (tau_west_spectral_gwd_flag) call tau_west_spectral_gwd%write_field() if (tau_north_spectral_gwd_flag) call tau_north_spectral_gwd%write_field() - if ( subroutine_timers ) call timer("spectral_gwd_diags") + if ( LPROF ) call stop_timing( id, 'diags.spectral_gwd' ) end subroutine output_diags_for_spectral_gwd end module spectral_gwd_diags_mod diff --git a/interfaces/physics_schemes_interface/source/kernel/bl_exp_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/bl_exp_kernel_mod.F90 index f5ab6605d..c63bc632f 100644 --- a/interfaces/physics_schemes_interface/source/kernel/bl_exp_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/bl_exp_kernel_mod.F90 @@ -40,7 +40,7 @@ module bl_exp_kernel_mod !> type, public, extends(kernel_type) :: bl_exp_kernel_type private - type(arg_type) :: meta_args(94) = (/ & + type(arg_type) :: meta_args(93) = (/ & arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), &! theta_in_wth arg_type(GH_FIELD, GH_REAL, GH_READ, W3), &! rho_in_w3 arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), &! rho_in_wth @@ -72,7 +72,6 @@ module bl_exp_kernel_mod arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_2),&! tile_temperature arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1),&! rhostar arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1),&! recip_l_mo_sea - arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1),&! h_blend_orog arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1),&! t1_sd arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1),&! q1_sd arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), &! dtl_mphys @@ -181,7 +180,6 @@ module bl_exp_kernel_mod !> @param[in] tile_temperature Surface tile temperatures !> @param[in] rhostar_2d Surface density !> @param[in] recip_l_mo_sea_2d Inverse Obukhov length over sea only - !> @param[in] h_blend_orog_2d Orographic blending height !> @param[in] t1_sd_2d StDev of level 1 temperature !> @param[in] q1_sd_2d StDev of level 1 humidity !> @param[in] dtl_mphys Microphysics liq temperature increment @@ -297,7 +295,6 @@ subroutine bl_exp_code(nlayers, seg_len, & tile_temperature, & rhostar_2d, & recip_l_mo_sea_2d, & - h_blend_orog_2d, & t1_sd_2d, & q1_sd_2d, & dtl_mphys, & @@ -479,8 +476,7 @@ subroutine bl_exp_code(nlayers, seg_len, & cumulus_2d, & shallow_flag, & level_parcel_top - real(kind=r_def), dimension(undf_2d), intent(in) :: h_blend_orog_2d, & - recip_l_mo_sea_2d, & + real(kind=r_def), dimension(undf_2d), intent(in) :: recip_l_mo_sea_2d, & rhostar_2d, & t1_sd_2d, q1_sd_2d, & sea_u_current, & @@ -549,7 +545,7 @@ subroutine bl_exp_code(nlayers, seg_len, & zh, dzh, wstar, wthvs, u_0_p, v_0_p, zlcl_uv, qsat_lcl, delthvu, & bl_type_1, bl_type_2, bl_type_3, bl_type_4, bl_type_5, bl_type_6, & bl_type_7, uw0, vw0, zhnl, rhostar, & - h_blend_orog, recip_l_mo_sea, flandg, t1_sd, q1_sd, qcl_inv_top, & + recip_l_mo_sea, flandg, t1_sd, q1_sd, qcl_inv_top, & fb_surf, rib_gb, z0m_eff_gb, zhsc, ustargbm, cos_theta_latitude, & max_diff, delta_smag, tnuc_nlcl_um real(r_um), dimension(seg_len,1) :: surf_dep_flux, zeroes @@ -652,7 +648,6 @@ subroutine bl_exp_code(nlayers, seg_len, & ustargbm(i,1) = ustar(map_2d(1,i)) rhostar(i,1) = rhostar_2d(map_2d(1,i)) recip_l_mo_sea(i,1) = recip_l_mo_sea_2d(map_2d(1,i)) - h_blend_orog(i,1) = h_blend_orog_2d(map_2d(1,i)) rib_gb(i,1) = gradrinr(map_wth(1,i)) z0m_eff_gb(i,1) = z0m_eff(map_2d(1,i)) ftl(i,1,1) = heat_flux_bl(map_w3(1,i)) @@ -895,8 +890,8 @@ subroutine bl_exp_code(nlayers, seg_len, & ! IN cloud/moisture data : bulk_cloud_fraction,q,qcf,qcl,temperature,qw,tl, & ! IN everything not covered so far : - rad_hr,micro_tends,fb_surf,ustargbm,p_star,tstar,h_blend_orog, & - zh_prev, zhpar,zlcl,ho2r2_orog_gb,sd_orog,wtrac_as, & + rad_hr,micro_tends,fb_surf,ustargbm,p_star,tstar, & + zh_prev, zhpar,zlcl,ho2r2_orog_gb,sd_orog,wtrac_as, & ! 2 IN 3 INOUT for Smagorinsky delta_smag, max_diff, rneutml_sq, visc_m, visc_h, & ! SCM Diagnostics (dummy values in full UM) & stash diag diff --git a/interfaces/physics_schemes_interface/source/kernel/conv_gr_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/conv_gr_kernel_mod.F90 index df4786f17..2fcf1d420 100644 --- a/interfaces/physics_schemes_interface/source/kernel/conv_gr_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/conv_gr_kernel_mod.F90 @@ -11,10 +11,11 @@ module conv_gr_kernel_mod GH_FIELD, GH_SCALAR, & GH_INTEGER, GH_REAL, & GH_READ, GH_WRITE, & - GH_READWRITE, CELL_COLUMN, & + GH_READWRITE, DOMAIN, & ANY_DISCONTINUOUS_SPACE_1, & ANY_DISCONTINUOUS_SPACE_2 use constants_mod, only : i_def, i_um, r_def, r_um + use tuning_segments_mod, only : conv_gr_segment_size use empty_data_mod, only : empty_real_data use fs_continuity_mod, only : W3, Wtheta use kernel_mod, only : kernel_type @@ -95,7 +96,7 @@ module conv_gr_kernel_mod arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! o3p arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! o1d arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! o3 - arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! n + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! nit arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! no arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! no3 arg_type(GH_FIELD, GH_REAL, GH_READWRITE, WTHETA ), & ! lumped_n @@ -245,7 +246,7 @@ module conv_gr_kernel_mod arg_type(GH_FIELD, GH_REAL, GH_WRITE, WTHETA), &! dth_conv_noshal arg_type(GH_FIELD, GH_REAL, GH_WRITE, WTHETA) &! dmv_conv_noshal /) - integer :: operates_on = CELL_COLUMN + integer :: operates_on = DOMAIN contains procedure, nopass :: conv_gr_code end type @@ -259,6 +260,7 @@ module conv_gr_kernel_mod !> vertical mixing of heat, momentum and moisture, !> as documented in UMDP27 !> @param[in] nlayers Number of layers + !> @param[in] ncells Number of cells !> @param[in] outer Outer loop counter !> @param[in] rho_in_w3 Density field in density space !> @param[in] rho_in_wth Density field in wth space @@ -320,7 +322,7 @@ module conv_gr_kernel_mod !> @param[in,out] o3p oxygen_ground_state m.m.r !> @param[in,out] o1d oxygen_excited_state m.m.r !> @param[in,out] o3 ozone m.m.r - !> @param[in,out] n nitrogen_radical m.m.r + !> @param[in,out] nit nitrogen_radical m.m.r !> @param[in,out] no nitric_oxide m.m.r !> @param[in,out] no3 nitrate_radical m.m.r !> @param[in,out] lumped_n lumped_n_as_nitrogen_dioxide m.m.r @@ -482,6 +484,7 @@ module conv_gr_kernel_mod !> @param[in] undf_tile Number of total DOFs for tiles !> @param[in] map_tile Dofmap for cell for surface tiles subroutine conv_gr_code(nlayers, & + ncells, & outer, & rho_in_w3, & rho_in_wth, & @@ -543,7 +546,7 @@ subroutine conv_gr_code(nlayers, & o3p, & o1d, & o3, & - n, & + nit, & no, & no3, & lumped_n, & @@ -844,7 +847,7 @@ subroutine conv_gr_code(nlayers, & use cv_param_mod, only: max_mf_fall, dthetadt_conv_active_threshold, & conv_prog_precip_min_threshold use jules_surface_mod, only: srf_ex_cnv_gust, IP_SrfExWithCnv - use nlsizes_namelist_mod, only: row_length, rows, bl_levels, n_cca_lev + use nlsizes_namelist_mod, only: bl_levels, n_cca_lev use pc2_constants_mod, only: i_cld_pc2 use planet_constants_mod, only: p_zero, kappa, planet_radius, g use scm_convss_dg_mod, only: scm_convss_dg_type @@ -860,18 +863,18 @@ subroutine conv_gr_code(nlayers, & implicit none ! Arguments - integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: nlayers, ncells integer(kind=i_def), intent(in) :: outer integer(kind=i_def), intent(in) :: ndf_wth, ndf_w3 integer(kind=i_def), intent(in) :: ndf_2d, undf_2d integer(kind=i_def), intent(in) :: undf_wth, undf_w3 - integer(kind=i_def), intent(in) :: map_wth(ndf_wth) - integer(kind=i_def), intent(in) :: map_w3(ndf_w3) - integer(kind=i_def), intent(in) :: map_2d(ndf_2d) + integer(kind=i_def), intent(in) :: map_wth(ndf_wth, ncells) + integer(kind=i_def), intent(in) :: map_w3(ndf_w3, ncells) + integer(kind=i_def), intent(in) :: map_2d(ndf_2d, ncells) integer(kind=i_def), intent(in) :: ndf_tile, undf_tile - integer(kind=i_def), intent(in) :: map_tile(ndf_tile) + integer(kind=i_def), intent(in) :: map_tile(ndf_tile, ncells) real(kind=r_def), dimension(undf_w3), intent(in) :: rho_in_w3, & wetrho_in_w3, & @@ -920,7 +923,7 @@ subroutine conv_gr_code(nlayers, & real(kind=r_def), intent(in out), dimension(undf_wth) :: o3p real(kind=r_def), intent(in out), dimension(undf_wth) :: o1d real(kind=r_def), intent(in out), dimension(undf_wth) :: o3 - real(kind=r_def), intent(in out), dimension(undf_wth) :: n + real(kind=r_def), intent(in out), dimension(undf_wth) :: nit real(kind=r_def), intent(in out), dimension(undf_wth) :: no real(kind=r_def), intent(in out), dimension(undf_wth) :: no3 real(kind=r_def), intent(in out), dimension(undf_wth) :: lumped_n @@ -1081,12 +1084,12 @@ subroutine conv_gr_code(nlayers, & ! Local variables for the kernel !----------------------------------------------------------------------- ! loop counters etc - integer(i_def) :: k, i + integer(i_def) :: k, i, n, ii, j ! local switches and scalars integer(i_um) :: n_deep, n_shallow, n_congestus, n_mid, & - ntra_lev, segments, n_conv_levels, & - call_number, ntra_fld, seg_num + ntra_lev, nml_segment_size, seg_size, n_conv_levels, & + call_number, ntra_fld, seg_num, num_seg logical :: l_tracer, l_calc_dxek, l_q_interact, l_scm_convss_dg @@ -1094,7 +1097,7 @@ subroutine conv_gr_code(nlayers, & decay_amount, conv_active, theta_inc_threshold ! profile fields from level 1 upwards - real(r_um), dimension(row_length,rows,nlayers) :: & + real(r_um), dimension(ncells,1,nlayers) :: & p_rho_levels, rho_wet, rho_dry, z_rho, z_theta, cca_3d, rho_wet_tq, & rho_dry_theta, exner_rho_levels, r_rho_levels, & theta_conv, q_conv, qcl_conv, qcf_conv, & @@ -1114,12 +1117,12 @@ subroutine conv_gr_code(nlayers, & it_dt_dd, it_dq_dd, tnuc_new ! profile fields from level 0 upwards - real(r_um), dimension(row_length,rows,0:nlayers) :: & + real(r_um), dimension(ncells,1,0:nlayers) :: & p_theta_levels, p_rho_minus_one, w, r_theta_levels, & exner_rho_minus_one, exner_theta_levels ! single level real fields - real(r_um), dimension(row_length,rows) :: & + real(r_um), dimension(ncells,1) :: & p_star, zhpar, zh, wstar, wthvs, zlcl_uv, entrain_coef, & qsat_lcl, delthvu, flandg, uw0, vw0, it_lcca, it_cca_2d, it_cclwp, & it_cclwp0, it_conv_rain, it_conv_snow, it_precip_dp, it_precip_sh, & @@ -1129,12 +1132,12 @@ subroutine conv_gr_code(nlayers, & delta_smag, tnuc_nlcl_um ! single level integer fields - integer(i_um), dimension(row_length,rows) :: ntml, ntpar, lcbase, & + integer(i_um), dimension(ncells,1) :: ntml, ntpar, lcbase, & it_lcbase,it_lctop, it_ccb, it_cct, it_ccb0, it_cct0, it_kterm_deep,& it_kterm_shall, it_cg_term, it_lcbase0, freeze_lev, ccb, cct, lctop ! single level logical fields - logical, dimension(row_length,rows) :: land_sea_mask, cumulus, & + logical, dimension(ncells,1) :: land_sea_mask, cumulus, & l_shallow, l_congestus, & it_mid_level, l_mid @@ -1153,150 +1156,174 @@ subroutine conv_gr_code(nlayers, & ! if they become set, please move up to be with other variables type(scm_convss_dg_type), allocatable :: scm_convss_dg(:) - real(r_um), dimension(row_length,rows,nlayers) :: & + real(r_um), dimension(ncells,1,nlayers) :: & it_mf_congest, it_dt_congest, it_dq_congest, it_du_congest, & it_dv_congest, it_du_dd, it_dv_dd, it_area_ud, it_area_dd, & it_uw_dp, it_vw_dp, it_uw_shall, it_vw_shall, & it_uw_mid, it_vw_mid, it_wqt_flux, it_wthetal_flux, it_wthetav_flux,& it_wql_flux, conv_prog_flx - real(r_um), dimension(row_length,rows,bl_levels) :: fqw, ftl + real(r_um), dimension(ncells,1) :: fqw, ftl - real(r_um), dimension(row_length,rows,nlayers) :: conv_prog_precip_conv + real(r_um), dimension(ncells,1,nlayers) :: conv_prog_precip_conv - real(r_um), dimension(row_length,rows) :: zlcl, t1_sd, q1_sd, w_max, & + real(r_um), dimension(ncells,1) :: zlcl, t1_sd, q1_sd, w_max, & deep_flag, past_conv_ht, ql_ad, ind_cape_reduced, & it_wstar_dn, g_ccp, h_ccp, ccp_strength - integer(i_um), dimension(row_length,rows) :: conv_type + integer(i_um), dimension(ncells,1) :: conv_type ! Water tracer fields which are not currently used but are required by ! UM routine - real(r_um), dimension(1,1,1) :: q_wtrac, qcl_wtrac, qcf_wtrac, & - dqbydt_wtrac, dqclbydt_wtrac, dqcfbydt_wtrac - real(r_um), dimension(1,1) :: rain_wtrac, snow_wtrac + real(r_um), dimension(ncells,nlayers,n_wtrac) :: q_wtrac, qcl_wtrac, & + qcf_wtrac, dqbydt_wtrac, dqclbydt_wtrac, dqcfbydt_wtrac + real(r_um), dimension(ncells,n_wtrac) :: rain_wtrac, snow_wtrac + + ! Current assumptions about setup based on GA9 + + ! If this is the last solver outer loop then tracers may need convecting. + ! Enable tracers for UKCA if a UKCA tracer list is available + ! (This indicates that a UKCA configuration has been set up) + if (outer == outer_iterations) then + if ( glomap_mode == glomap_mode_dust_and_clim ) then + ukca_tracer_names => local_dust_tracer_list + l_tracer = .true. + else + call ukca_get_tracer_varlist( ukca_tracer_names, ukca_errcode ) + l_tracer = ( ukca_errcode == 0 ) + end if + else + l_tracer = .false. + end if + + if ( outer == outer_iterations .AND. l_tracer ) then + + ntra_fld = size(ukca_tracer_names) + ntra_lev = nlayers + allocate(tot_tracer( ncells, 1, ntra_lev, ntra_fld )) + + else + + ! No tracers: set up a dummy tracer array + ntra_fld = 1 + ntra_lev = 1 + allocate(tot_tracer( ncells, 1, ntra_lev, ntra_fld )) + + end if ! outer == outer_iterations .AND. l_tracer !----------------------------------------------------------------------- ! Mapping of LFRic fields into UM variables !----------------------------------------------------------------------- + ! Land sea mask - flandg = 0.0_r_um - do i = 1, n_land_tile - flandg = flandg + real(tile_fraction(map_tile(1)+i-1), r_um) + do i = 1, ncells + flandg(i,1) = 0.0_r_um + do n = 1, n_land_tile + flandg(i,1) = flandg(i,1) + real(tile_fraction(map_tile(1,i)+n-1), r_um) + end do + end do + do i = 1, ncells + ! Jules requires fractions with respect to the land area + if (flandg(i,1) > 0.0_r_um) then + land_sea_mask(i,1) = .true. + else + land_sea_mask(i,1) = .false. + end if end do - - ! Jules requires fractions with respect to the land area - if (flandg(1, 1) > 0.0_r_um) then - land_sea_mask = .true. - else - land_sea_mask = .false. - end if !----------------------------------------------------------------------- - ! For the initial implementation we pass each individual column - ! of data to an array sized (1,1,k) to match the UMs (i,j,k) data - ! layout. - ! assuming map_wth(1) points to level 0 - ! and map_w3(1) points to level 1 + ! Build vectors of columns in the horizontal by copying data to + ! arrays sized (i,1,k) to match the UMs (i,j,k) data layout. + ! Assuming map_wth(1,i) points to level 0 + ! and map_w3(1,i) points to level 1 !----------------------------------------------------------------------- do k = 0, nlayers - ! pressure on theta levels - p_theta_levels(1,1,k) = p_zero*(exner_in_wth(map_wth(1) + k))**(1.0_r_def/kappa) - ! exner pressure on theta levels - exner_theta_levels(1,1,k) = exner_in_wth(map_wth(1) + k) - ! height of theta levels from centre of planet - r_theta_levels(1,1,k) = height_wth(map_wth(1) + k) + planet_radius - ! w wind on theta levels - w(1,1,k) = w_in_wth(map_wth(1) + k) + do i = 1, ncells + ! pressure on theta levels + p_theta_levels(i,1,k) = p_zero*(exner_in_wth(map_wth(1,i) + k))**(1.0_r_def/kappa) + ! exner pressure on theta levels + exner_theta_levels(i,1,k) = exner_in_wth(map_wth(1,i) + k) + ! height of theta levels from centre of planet + r_theta_levels(i,1,k) = height_wth(map_wth(1,i) + k) + planet_radius + ! w wind on theta levels + w(i,1,k) = w_in_wth(map_wth(1,i) + k) + end do end do do k = 1, nlayers - ! wet density on theta and rho levels - rho_wet_tq(1,1,k) = wetrho_in_wth(map_wth(1) + k) - rho_wet(1,1,k) = wetrho_in_w3(map_w3(1) + k-1) - ! dry density on theta and rho levels - rho_dry_theta(1,1,k) = rho_in_wth(map_wth(1) + k) - rho_dry(1,1,k) = rho_in_w3(map_w3(1) + k-1) - ! pressure on rho levels - p_rho_levels(1,1,k) = p_zero*(exner_in_w3(map_w3(1) + k-1))**(1.0_r_def/kappa) - ! exner pressure on rho levels - exner_rho_levels(1,1,k) = exner_in_w3(map_w3(1) + k-1) - ! height of rho levels from centre of planet - r_rho_levels(1,1,k) = height_w3(map_w3(1) + k-1) + planet_radius + do i = 1, ncells + ! wet density on theta and rho levels + rho_wet_tq(i,1,k) = wetrho_in_wth(map_wth(1,i) + k) + rho_wet(i,1,k) = wetrho_in_w3(map_w3(1,i) + k-1) + ! dry density on theta and rho levels + rho_dry_theta(i,1,k) = rho_in_wth(map_wth(1,i) + k) + rho_dry(i,1,k) = rho_in_w3(map_w3(1,i) + k-1) + ! pressure on rho levels + p_rho_levels(i,1,k) = p_zero*(exner_in_w3(map_w3(1,i) + k-1))**(1.0_r_def/kappa) + ! exner pressure on rho levels + exner_rho_levels(i,1,k) = exner_in_w3(map_w3(1,i) + k-1) + ! height of rho levels from centre of planet + r_rho_levels(i,1,k) = height_w3(map_w3(1,i) + k-1) + planet_radius + end do end do if ( smagorinsky ) then - delta_smag(1,1) = delta(map_wth(1)) + do i = 1, ncells + delta_smag(i,1) = delta(map_wth(1,i)) + end do end if - ! surface pressure - p_star(1,1) = p_theta_levels(1,1,0) - ! setup odd array which is on rho levels but without level 1 - p_rho_minus_one(1,1,0) = p_theta_levels(1,1,0) - do k = 1, nlayers-1 - p_rho_minus_one(1,1,k) = p_rho_levels(1,1,k+1) - end do - p_rho_minus_one(1,1,nlayers) = 0.0_r_um - ! and similar array for exner - exner_rho_minus_one(1,1,0) = exner_theta_levels(1,1,0) - do k = 1, nlayers-1 - exner_rho_minus_one(1,1,k) = exner_rho_levels(1,1,k+1) - end do - exner_rho_minus_one(1,1,nlayers) = 0.0_r_um - ! height of levels above surface - do k = 1, nlayers - z_rho(1,1,k) = r_rho_levels(1,1,k)-r_theta_levels(1,1,0) - z_theta(1,1,k) = r_theta_levels(1,1,k)-r_theta_levels(1,1,0) + do i = 1, ncells + ! surface pressure + p_star(i,1) = p_theta_levels(i,1,0) + ! setup odd array which is on rho levels but without level 1 + p_rho_minus_one(i,1,0) = p_theta_levels(i,1,0) + do k = 1, nlayers-1 + p_rho_minus_one(i,1,k) = p_rho_levels(i,1,k+1) + end do + p_rho_minus_one(i,1,nlayers) = 0.0_r_um + ! and similar array for exner + exner_rho_minus_one(i,1,0) = exner_theta_levels(i,1,0) + do k = 1, nlayers-1 + exner_rho_minus_one(i,1,k) = exner_rho_levels(i,1,k+1) + end do + exner_rho_minus_one(i,1,nlayers) = 0.0_r_um + ! height of levels above surface + do k = 1, nlayers + z_rho(i,1,k) = r_rho_levels(i,1,k)-r_theta_levels(i,1,0) + z_theta(i,1,k) = r_theta_levels(i,1,k)-r_theta_levels(i,1,0) + end do end do !----------------------------------------------------------------------- ! Things passed from other parametrization schemes on this timestep - !----------------------------------------------------------------------- - cumulus(1,1) = (cumulus_2d(map_2d(1)) == 1_i_def) - ntml(1,1) = ntml_2d(map_2d(1)) - - zh(1,1) = zh_2d(map_2d(1)) - l_shallow(1,1) = (shallow_flag(map_2d(1)) == 1_i_def) - uw0(1,1) = uw0_flux(map_2d(1)) - vw0(1,1) = vw0_flux(map_2d(1)) - zlcl_uv(1,1) = lcl_height(map_2d(1)) - zhpar(1,1) = parcel_top(map_2d(1)) - ntpar(1,1) = level_parcel_top(map_2d(1)) - wstar(1,1) = wstar_2d(map_2d(1)) - wthvs(1,1) = thv_flux(map_2d(1)) - delthvu(1,1) = parcel_buoyancy(map_2d(1)) - qsat_lcl(1,1) = qsat_at_lcl(map_2d(1)) + !---------------------------------------------------------------------- + do i = 1, ncells + cumulus(i,1) = (cumulus_2d(map_2d(1,i)) == 1_i_def) + ntml(i,1) = ntml_2d(map_2d(1,i)) + + zh(i,1) = zh_2d(map_2d(1,i)) + l_shallow(i,1) = (shallow_flag(map_2d(1,i)) == 1_i_def) + uw0(i,1) = uw0_flux(map_2d(1,i)) + vw0(i,1) = vw0_flux(map_2d(1,i)) + zlcl_uv(i,1) = lcl_height(map_2d(1,i)) + zhpar(i,1) = parcel_top(map_2d(1,i)) + ntpar(i,1) = level_parcel_top(map_2d(1,i)) + wstar(i,1) = wstar_2d(map_2d(1,i)) + wthvs(i,1) = thv_flux(map_2d(1,i)) + delthvu(i,1) = parcel_buoyancy(map_2d(1,i)) + qsat_lcl(i,1) = qsat_at_lcl(map_2d(1,i)) + end do !======================================================================== ! Call to 6A Gregory-Rowntree convection scheme !======================================================================== - ! Current assumptions about setup based on GA9 - - ! If this is the last solver outer loop then tracers may need convecting. - ! Enable tracers for UKCA if a UKCA tracer list is available - ! (This indicates that a UKCA configuration has been set up) - if (outer == outer_iterations) then - if ( glomap_mode == glomap_mode_dust_and_clim ) then - ukca_tracer_names => local_dust_tracer_list - l_tracer = .true. - else - call ukca_get_tracer_varlist( ukca_tracer_names, ukca_errcode ) - l_tracer = ( ukca_errcode == 0 ) - end if - else - l_tracer = .false. - end if l_calc_dxek = ( i_cld_vn == i_cld_pc2 ) l_q_interact = l_calc_dxek l_congestus = .false. ! never used in GA9 entrain_coef = -99.0_r_um ! unused default value - segments = 1 ! i.e. one column - seg_num = map_wth(1) ! Only used by debugging error message from UM - ! This is probably most useful to indicate - ! which column has a problem - n_conv_levels = nlayers if (l_mom) then ! Limit convection calling levels to maximum of model_levels - 1 @@ -1311,419 +1338,661 @@ subroutine conv_gr_code(nlayers, & ! Sub-timestep scheme one_over_conv_calls = 1.0_r_um/real(n_conv_calls) - l_mid(1,1) = .true. + do i = 1, ncells + l_mid(i,1) = .true. + end do do k=1,nlayers - ! Pointing to _star values - theta_conv(1,1,k) = theta_star(map_wth(1) + k) - q_conv(1,1,k) = m_v(map_wth(1) + k) - qcl_conv(1,1,k) = m_cl(map_wth(1) + k) - qcf_conv(1,1,k) = m_cf(map_wth(1) + k) - - cf_liquid_conv(1,1,k) = cf_liq(map_wth(1) + k) - cf_frozen_conv(1,1,k) = cf_ice(map_wth(1) + k) - bulk_cf_conv(1,1,k) = cf_bulk(map_wth(1) + k) - ! Total theta increment - dtheta_conv(1,1,k) = 0.0_r_um - cca_3d(1,1,k) = 0.0_r_um - ccw_3d(1,1,k) = 0.0_r_um + do i = 1, ncells + ! Pointing to _star values + theta_conv(i,1,k) = theta_star(map_wth(1,i) + k) + q_conv(i,1,k) = m_v(map_wth(1,i) + k) + qcl_conv(i,1,k) = m_cl(map_wth(1,i) + k) + qcf_conv(i,1,k) = m_cf(map_wth(1,i) + k) + + cf_liquid_conv(i,1,k) = cf_liq(map_wth(1,i) + k) + cf_frozen_conv(i,1,k) = cf_ice(map_wth(1,i) + k) + bulk_cf_conv(i,1,k) = cf_bulk(map_wth(1,i) + k) + ! Total theta increment + dtheta_conv(i,1,k) = 0.0_r_um + cca_3d(i,1,k) = 0.0_r_um + ccw_3d(i,1,k) = 0.0_r_um + end do end do if (l_conv_prog_precip) then do k = 1, nlayers - conv_prog_precip_conv(1,1,k) = conv_prog_precip(map_wth(1) + k) + do i = 1, ncells + conv_prog_precip_conv(i,1,k) = conv_prog_precip(map_wth(1,i) + k) + end do end do end if - ccb(1,1) = 0_i_um - cct(1,1) = 0_i_um - lctop(1,1) = 0_i_um - lcbase(1,1) = 0_i_um - w_max(1,1) = 0.0_r_um + do i = 1, ncells + ccb(i,1) = 0_i_um + cct(i,1) = 0_i_um + lctop(i,1) = 0_i_um + lcbase(i,1) = 0_i_um + w_max(i,1) = 0.0_r_um + end do ! Turn water tracers off in convection and initialise dummy fields l_wtrac_conv = .FALSE. + do k = 1,n_wtrac + do j = 1,nlayers + do i = 1,ncells + q_wtrac(i,j,k) = 0.0_r_um + qcl_wtrac(i,j,k) = 0.0_r_um + qcf_wtrac(i,j,k) = 0.0_r_um + dqbydt_wtrac(i,j,k) = 0.0_r_um + dqclbydt_wtrac(i,j,k) = 0.0_r_um + dqcfbydt_wtrac(i,j,k) = 0.0_r_um + end do + end do + end do + do j = 1,n_wtrac + do i = 1,ncells + rain_wtrac(i,j) = 0.0_r_um + snow_wtrac(i,j) = 0.0_r_um + end do + end do + ! Check for negative (less than a minimum) q being passed to convection if (l_safe_conv) then do k=1,nlayers - if (q_conv(1,1,k) < qmin_conv) then - ! Should really be warning print statements if this is happening - ! but log_event calls not allowed. - ! store q added to ensure sensible profile - dq_add(1,1,k) = qmin_conv - q_conv(1,1,k) - ! Reset to qmin in non-conservative way - q_conv(1,1,k) = qmin_conv - else - dq_add(1,1,k) = 0.0_r_um - end if + do i = 1, ncells + if (q_conv(i,1,k) < qmin_conv) then + ! Should really be warning print statements if this is happening + ! but log_event calls not allowed. + ! store q added to ensure sensible profile + dq_add(i,1,k) = qmin_conv - q_conv(i,1,k) + ! Reset to qmin in non-conservative way + q_conv(i,1,k) = qmin_conv + else + dq_add(i,1,k) = 0.0_r_um + end if + end do ! i end do ! k end if if (l_mom) then do k=1,nlayers - u_conv(1,1,k) = u_in_w3_star(map_w3(1) + k-1) - v_conv(1,1,k) = v_in_w3_star(map_w3(1) + k-1) + do i = 1, ncells + u_conv(i,1,k) = u_in_w3_star(map_w3(1,i) + k-1) + v_conv(i,1,k) = v_in_w3_star(map_w3(1,i) + k-1) + end do ! i end do ! k end if ! Map tracer fields to UM tracer array if ( outer == outer_iterations .AND. l_tracer ) then - - ntra_fld = size(ukca_tracer_names) - ntra_lev = nlayers - allocate(tot_tracer( 1, 1, ntra_lev, ntra_fld )) - - do i = 1, ntra_fld - select case(ukca_tracer_names(i)) + do n = 1, ntra_fld + select case(ukca_tracer_names(n)) case(fldname_o3p) - tot_tracer( 1, 1, :, i ) = & - real( o3p( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( o3p( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_o1d) - tot_tracer( 1, 1, :, i ) = & - real( o1d( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( o1d( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_o3) - tot_tracer( 1, 1, :, i ) = & - real( o3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( o3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n) - tot_tracer( 1, 1, :, i ) = & - real( n( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( nit( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_no) - tot_tracer( 1, 1, :, i ) = & - real( no( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( no( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_no3) - tot_tracer( 1, 1, :, i ) = & - real( no3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( no3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_lumped_n) - tot_tracer( 1, 1, :, i ) = & - real( lumped_n( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( lumped_n( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n2o5) - tot_tracer( 1, 1, :, i ) = & - real( n2o5( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n2o5( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ho2no2) - tot_tracer( 1, 1, :, i ) = & - real( ho2no2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ho2no2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hono2) - tot_tracer( 1, 1, :, i ) = & - real( hono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_h2o2) - tot_tracer( 1, 1, :, i ) = & - real( h2o2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( h2o2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ch4) - tot_tracer( 1, 1, :, i ) = & - real( ch4( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ch4( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_co) - tot_tracer( 1, 1, :, i ) = & - real( co( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( co( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hcho) - tot_tracer( 1, 1, :, i ) = & - real( hcho( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hcho( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_meoo) - tot_tracer( 1, 1, :, i ) = & - real( meoo( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( meoo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_meooh) - tot_tracer( 1, 1, :, i ) = & - real( meooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( meooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_h) - tot_tracer( 1, 1, :, i ) = & - real( h( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( h( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ch2o) - ! H2O tracer from chemistry is not transported - tot_tracer( 1, 1, :, i ) = 0.0_r_um + do i = 1, ncells + ! H2O tracer from chemistry ns not transported + tot_tracer( i, 1, :, n ) = 0.0_r_um + end do case(fldname_oh) - tot_tracer( 1, 1, :, i ) = & - real( oh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( oh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ho2) - tot_tracer( 1, 1, :, i ) = & - real( ho2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ho2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cl) - tot_tracer( 1, 1, :, i ) = & - real( cl( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cl2o2) - tot_tracer( 1, 1, :, i ) = & - real( cl2o2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cl2o2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_clo) - tot_tracer( 1, 1, :, i ) = & - real( clo( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( clo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_oclo) - tot_tracer( 1, 1, :, i ) = & - real( oclo( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( oclo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_br) - tot_tracer( 1, 1, :, i ) = & - real( br( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( br( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_lumped_br) - tot_tracer( 1, 1, :, i ) = & - real( lumped_br( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( lumped_br( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_brcl) - tot_tracer( 1, 1, :, i ) = & - real( brcl( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( brcl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_brono2) - tot_tracer( 1, 1, :, i ) = & - real( brono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( brono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n2o) - tot_tracer( 1, 1, :, i ) = & - real( n2o( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n2o( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_lumped_cl) - tot_tracer( 1, 1, :, i ) = & - real( lumped_cl( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( lumped_cl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hocl) - tot_tracer( 1, 1, :, i ) = & - real( hocl( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hocl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hbr) - tot_tracer( 1, 1, :, i ) = & - real( hbr( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hbr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hobr) - tot_tracer( 1, 1, :, i ) = & - real( hobr( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hobr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_clono2) - tot_tracer( 1, 1, :, i ) = & - real( clono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( clono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cfcl3) - tot_tracer( 1, 1, :, i ) = & - real( cfcl3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cfcl3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cf2cl2) - tot_tracer( 1, 1, :, i ) = & - real( cf2cl2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cf2cl2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_mebr) - tot_tracer( 1, 1, :, i ) = & - real( mebr( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( mebr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hono) - tot_tracer( 1, 1, :, i ) = & - real( hono( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hono( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_c2h6) - tot_tracer( 1, 1, :, i ) = & - real( c2h6( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( c2h6( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_etoo) - tot_tracer( 1, 1, :, i ) = & - real( etoo( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( etoo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_etooh) - tot_tracer( 1, 1, :, i ) = & - real( etooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( etooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_mecho) - tot_tracer( 1, 1, :, i ) = & - real( mecho( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( mecho( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_meco3) - tot_tracer( 1, 1, :, i ) = & - real( meco3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( meco3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_pan) - tot_tracer( 1, 1, :, i ) = & - real( pan( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( pan( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_c3h8) - tot_tracer( 1, 1, :, i ) = & - real( c3h8( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( c3h8( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n_proo) - tot_tracer( 1, 1, :, i ) = & - real( n_proo( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_proo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_i_proo) - tot_tracer( 1, 1, :, i ) = & - real( i_proo( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( i_proo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n_prooh) - tot_tracer( 1, 1, :, i ) = & - real( n_prooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_prooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_i_prooh) - tot_tracer( 1, 1, :, i ) = & - real( i_prooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( i_prooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_etcho) - tot_tracer( 1, 1, :, i ) = & - real( etcho( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( etcho( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_etco3) - tot_tracer( 1, 1, :, i ) = & - real( etco3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( etco3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_me2co) - tot_tracer( 1, 1, :, i ) = & - real( me2co( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( me2co( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_mecoch2oo) - tot_tracer( 1, 1, :, i ) = & - real( mecoch2oo( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( mecoch2oo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_mecoch2ooh) - tot_tracer( 1, 1, :, i ) = & - real( mecoch2ooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( mecoch2ooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ppan) - tot_tracer( 1, 1, :, i ) = & - real( ppan( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ppan( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_meono2) - tot_tracer( 1, 1, :, i ) = & - real( meono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( meono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_c5h8) - tot_tracer( 1, 1, :, i ) = & - real( c5h8( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( c5h8( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_iso2) - tot_tracer( 1, 1, :, i ) = & - real( iso2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( iso2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_isooh) - tot_tracer( 1, 1, :, i ) = & - real( isooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( isooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ison) - tot_tracer( 1, 1, :, i ) = & - real( ison( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ison( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_macr) - tot_tracer( 1, 1, :, i ) = & - real( macr( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( macr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_macro2) - tot_tracer( 1, 1, :, i ) = & - real( macro2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( macro2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_macrooh) - tot_tracer( 1, 1, :, i ) = & - real( macrooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( macrooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_mpan) - tot_tracer( 1, 1, :, i ) = & - real( mpan( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( mpan( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hacet) - tot_tracer( 1, 1, :, i ) = & - real( hacet( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hacet( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_mgly) - tot_tracer( 1, 1, :, i ) = & - real( mgly( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( mgly( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_nald) - tot_tracer( 1, 1, :, i ) = & - real( nald( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( nald( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_hcooh) - tot_tracer( 1, 1, :, i ) = & - real( hcooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( hcooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_meco3h) - tot_tracer( 1, 1, :, i ) = & - real( meco3h( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( meco3h( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_meco2h) - tot_tracer( 1, 1, :, i ) = & - real( meco2h( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( meco2h( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_h2) - tot_tracer( 1, 1, :, i ) = & - real( h2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( h2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_meoh) - tot_tracer( 1, 1, :, i ) = & - real( meoh( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( meoh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_msa) - tot_tracer( 1, 1, :, i ) = & - real( msa( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( msa( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_nh3) - tot_tracer( 1, 1, :, i ) = & - real( nh3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( nh3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cs2) - tot_tracer( 1, 1, :, i ) = & - real( cs2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cs2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_csul) - tot_tracer( 1, 1, :, i ) = & - real( csul( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( csul( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_h2s) - tot_tracer( 1, 1, :, i ) = & - real( h2s( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( h2s( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_so3) - tot_tracer( 1, 1, :, i ) = & - real( so3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( so3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_passive_o3) - tot_tracer( 1, 1, :, i ) = & - real( passive_o3( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( passive_o3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_age_of_air) - tot_tracer( 1, 1, :, i ) = & - real( age_of_air( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( age_of_air( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_dms) - tot_tracer( 1, 1, :, i ) = & - real( dms( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( dms( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_so2) - tot_tracer( 1, 1, :, i ) = & - real( so2( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( so2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_h2so4) - tot_tracer( 1, 1, :, i ) = & - real( h2so4( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( h2so4( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_dmso) - tot_tracer( 1, 1, :, i ) = & - real( dmso( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( dmso( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_monoterpene) - tot_tracer( 1, 1, :, i ) = & - real( monoterpene( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( monoterpene( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_secondary_organic) - tot_tracer( 1, 1, :, i ) = & - real( secondary_organic( map_wth(1) + 1 : map_wth(1) + ntra_lev ), & - r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( secondary_organic( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), & + r_um ) + end do case(fldname_n_nuc_sol) - tot_tracer( 1, 1, :, i ) = & - real( n_nuc_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_nuc_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_nuc_sol_su) - tot_tracer( 1, 1, :, i ) = & - real( nuc_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( nuc_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_nuc_sol_om) - tot_tracer( 1, 1, :, i ) = & - real( nuc_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( nuc_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n_ait_sol) - tot_tracer( 1, 1, :, i ) = & - real( n_ait_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_ait_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ait_sol_su) - tot_tracer( 1, 1, :, i ) = & - real( ait_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ait_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ait_sol_bc) - tot_tracer( 1, 1, :, i ) = & - real( ait_sol_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ait_sol_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ait_sol_om) - tot_tracer( 1, 1, :, i ) = & - real( ait_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ait_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n_acc_sol) - tot_tracer( 1, 1, :, i ) = & - real( n_acc_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_acc_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_acc_sol_su) - tot_tracer( 1, 1, :, i ) = & - real( acc_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( acc_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_acc_sol_bc) - tot_tracer( 1, 1, :, i ) = & - real( acc_sol_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( acc_sol_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_acc_sol_om) - tot_tracer( 1, 1, :, i ) = & - real( acc_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( acc_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_acc_sol_ss) - tot_tracer( 1, 1, :, i ) = & - real( acc_sol_ss( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( acc_sol_ss( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_acc_sol_du) - tot_tracer( 1, 1, :, i ) = 0.0_r_um ! no prognostic, always zero + do i = 1, ncells + tot_tracer( i, 1, :, n ) = 0.0_r_um ! no prognostic, always zero + end do case(fldname_n_cor_sol) - tot_tracer( 1, 1, :, i ) = & - real( n_cor_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_cor_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cor_sol_su) - tot_tracer( 1, 1, :, i ) = & - real( cor_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cor_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cor_sol_bc) - tot_tracer( 1, 1, :, i ) = & - real( cor_sol_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cor_sol_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cor_sol_om) - tot_tracer( 1, 1, :, i ) = & - real( cor_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cor_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cor_sol_ss) - tot_tracer( 1, 1, :, i ) = & - real( cor_sol_ss( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cor_sol_ss( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cor_sol_du) - tot_tracer( 1, 1, :, i ) = 0.0_r_um ! no prognostic, always zero + do i = 1, ncells + tot_tracer( i, 1, :, n ) = 0.0_r_um ! no prognostic, always zero + end do case(fldname_n_ait_ins) - tot_tracer( 1, 1, :, i ) = & - real( n_ait_ins( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_ait_ins( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ait_ins_bc) - tot_tracer( 1, 1, :, i ) = & - real( ait_ins_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ait_ins_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_ait_ins_om) - tot_tracer( 1, 1, :, i ) = & - real( ait_ins_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( ait_ins_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n_acc_ins) - tot_tracer( 1, 1, :, i ) = & - real( n_acc_ins( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_acc_ins( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_acc_ins_du) - tot_tracer( 1, 1, :, i ) = & - real( acc_ins_du( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( acc_ins_du( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_n_cor_ins) - tot_tracer( 1, 1, :, i ) = & - real( n_cor_ins( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( n_cor_ins( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case(fldname_cor_ins_du) - tot_tracer( 1, 1, :, i ) = & - real( cor_ins_du( map_wth(1) + 1 : map_wth(1) + ntra_lev ), r_um ) + do i = 1, ncells + tot_tracer( i, 1, :, n ) = & + real( cor_ins_du( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ), r_um ) + end do case default write( log_scratch_space, '(A,A)' ) & - 'Missing required UKCA tracer field: ', ukca_tracer_names(i) + 'Missing required UKCA tracer field: ', ukca_tracer_names(n) call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end select end do - - else - - ! No tracers: set up a dummy tracer array - ntra_fld = 1 - ntra_lev = 1 - allocate(tot_tracer( 1, 1, ntra_lev, ntra_fld )) - end if ! outer == outer_iterations .AND. l_tracer ! We do not want any sub-timestep SCM diagnostics but we still have @@ -1733,406 +2002,542 @@ subroutine conv_gr_code(nlayers, & l_scm_convss_dg = .false. allocate( scm_convss_dg(0) ) - n_congestus = 0 - n_deep = 0 - n_shallow = 0 - - if (cumulus(1,1)) then - if (iconv_deep > 0 .AND. .NOT. l_shallow(1,1) ) then - n_deep = 1 - endif - if (iconv_shallow > 0 .AND. l_shallow(1,1) ) then - n_shallow = 1 - endif - n_congestus = 1 ! as UM though not actually using scheme - end if - ! Loop over convection calls per model time step do call_number = 1, n_conv_calls - if (l_mid(1,1)) then - n_mid = 1 - else - n_mid = 0 - end if - ! Initialise convection work arrays holding information from each ! iteration (sub-step) do k = 1, n_cca_lev - it_cca(1,1,k) = 0.0_r_um - it_cca0(1,1,k) = 0.0_r_um - it_cca0_dp(1,1,k) = 0.0_r_um - it_cca0_sh(1,1,k) = 0.0_r_um - it_cca0_md(1,1,k) = 0.0_r_um + do i = 1, ncells + it_cca(i,1,k) = 0.0_r_um + it_cca0(i,1,k) = 0.0_r_um + it_cca0_dp(i,1,k) = 0.0_r_um + it_cca0_sh(i,1,k) = 0.0_r_um + it_cca0_md(i,1,k) = 0.0_r_um + end do end do do k = 1, nlayers - it_ccw(1,1,k) = 0.0_r_um - it_ccw0(1,1,k) = 0.0_r_um - it_conv_rain_3d(1,1,k) = 0.0_r_um - it_conv_snow_3d(1,1,k) = 0.0_r_um - it_w2p(1,1,k) = 0.0_r_um - it_up_flux(1,1,k) = 0.0_r_um + do i = 1, ncells + it_ccw(i,1,k) = 0.0_r_um + it_ccw0(i,1,k) = 0.0_r_um + it_conv_rain_3d(i,1,k) = 0.0_r_um + it_conv_snow_3d(i,1,k) = 0.0_r_um + it_w2p(i,1,k) = 0.0_r_um + it_up_flux(i,1,k) = 0.0_r_um + end do end do - it_lcca(1,1) = 0.0_r_um - it_lcbase(1,1) = 0 - it_lctop(1,1) = 0 - - it_ccb(1,1) = 0 - it_cct(1,1) = 0 - it_cca_2d(1,1) = 0.0_r_um - it_cclwp(1,1) = 0.0_r_um - - it_ccb0(1,1) = 0 - it_cct0(1,1) = 0 - it_cclwp0(1,1) = 0.0_r_um - - it_conv_rain(1,1) = 0.0_r_um - it_conv_snow(1,1) = 0.0_r_um - it_precip_dp(1,1) = 0.0_r_um - it_precip_sh(1,1) = 0.0_r_um - it_precip_md(1,1) = 0.0_r_um - it_cape_diluted(1,1) = 0.0_r_um - it_kterm_deep(1,1) = 0 - it_kterm_shall(1,1) = 0 - it_mid_level(1,1) = .FALSE. - it_dp_cfl_limited(1,1) = 0.0_r_um - it_md_cfl_limited(1,1) = 0.0_r_um - - it_precip_cg(1,1) = 0.0_r_um - it_wstar_up(1,1) = 0.0_r_um - it_mb1(1,1) = 0.0_r_um - it_mb2(1,1) = 0.0_r_um - it_cg_term(1,1) = 0 + do i = 1, ncells + it_lcca(i,1) = 0.0_r_um + it_lcbase(i,1) = 0 + it_lctop(i,1) = 0 + + it_ccb(i,1) = 0 + it_cct(i,1) = 0 + it_cca_2d(i,1) = 0.0_r_um + it_cclwp(i,1) = 0.0_r_um + + it_ccb0(i,1) = 0 + it_cct0(i,1) = 0 + it_cclwp0(i,1) = 0.0_r_um + + it_conv_rain(i,1) = 0.0_r_um + it_conv_snow(i,1) = 0.0_r_um + it_precip_dp(i,1) = 0.0_r_um + it_precip_sh(i,1) = 0.0_r_um + it_precip_md(i,1) = 0.0_r_um + it_cape_diluted(i,1) = 0.0_r_um + it_kterm_deep(i,1) = 0 + it_kterm_shall(i,1) = 0 + it_mid_level(i,1) = .FALSE. + it_dp_cfl_limited(i,1) = 0.0_r_um + it_md_cfl_limited(i,1) = 0.0_r_um + + it_precip_cg(i,1) = 0.0_r_um + it_wstar_up(i,1) = 0.0_r_um + it_mb1(i,1) = 0.0_r_um + it_mb2(i,1) = 0.0_r_um + it_cg_term(i,1) = 0 + end do if (prog_tnuc) then ! Use tnuc from LFRic and map onto tnuc_new for UM to be passed to glue_conv_6a do k = 1, nlayers - tnuc_new(1,1,k) = real(tnuc(map_wth(1) + k),kind=r_um) + do i = 1, ncells + tnuc_new(i,1,k) = real(tnuc(map_wth(1,i) + k),kind=r_um) + end do ! i end do ! k ! Use tnuc_nlcl from LFRic and map onto tnuc_nlcl_um for UM to the be passed to glue_conv_6a - tnuc_nlcl_um(1,1) = real(tnuc_nlcl(map_2d(1)),kind=r_um) + do i = 1, ncells + tnuc_nlcl_um(i,1) = real(tnuc_nlcl(map_2d(1,i)),kind=r_um) + end do end if - call glue_conv_6a & - ( rows*row_length, segments, n_conv_levels, n_wtrac, bl_levels & - , call_number, seg_num, theta_conv, q_conv, qcl_conv, qcf_conv & - , q_wtrac, qcl_wtrac, qcf_wtrac & - , cf_liquid_conv, cf_frozen_conv, bulk_cf_conv & - , p_star, land_sea_mask & - , u_conv, v_conv, w(1,1,1) & - , tot_tracer, dthbydt, dqbydt, dqclbydt, dqcfbydt & - , dcflbydt, dcffbydt, dbcfbydt, dubydt_p, dvbydt_p & - , dqbydt_wtrac, dqclbydt_wtrac, dqcfbydt_wtrac & - , it_conv_rain, it_conv_snow, it_conv_rain_3d, it_conv_snow_3d & - , rain_wtrac, snow_wtrac & - , it_cca0_dp, it_cca0_md, it_cca0_sh & - , it_cca0, it_ccb0, it_cct0, it_cclwp0, it_ccw0, it_lcbase0 & - , it_lctop, it_lcca & - , it_cca, it_ccb, it_cct, it_cclwp, it_ccw, it_lcbase & - , it_cca_2d, freeze_lev, it_dp_cfl_limited, it_md_cfl_limited & - , it_mid_level, it_kterm_deep, it_kterm_shall & - , it_precip_dp, it_precip_sh, it_precip_md, it_precip_cg & - , it_wstar_dn, it_wstar_up & - , it_mb1, it_mb2, it_cg_term & - , uw0, vw0, w_max & - , zlcl, zlcl_uv, tnuc_new, tnuc_nlcl_um, zhpar, entrain_coef & - , conv_prog_precip_conv, conv_prog_flx, deep_flag & - , past_conv_ht, it_cape_diluted, n_deep, n_congestus, n_shallow & - , n_mid, r_rho_levels, r_theta_levels & - , rho_wet, rho_wet_tq, rho_dry, rho_dry_theta, delta_smag & - , exner_rho_levels, exner_rho_minus_one, exner_theta_levels & - , p_rho_minus_one, p_theta_levels & - , z_theta, z_rho, timestep_conv & - , t1_sd, q1_sd, ntml, ntpar & - , conv_type, l_shallow & - , l_congestus, l_mid, cumulus & - , wstar, wthvs, delthvu, ql_ad, qsat_lcl, ftl, fqw & - , l_tracer, ntra_fld, ntra_lev, n_cca_lev & - , l_calc_dxek , l_q_interact & - , it_up_flux_half, it_up_flux, it_dwn_flux & - , it_entrain_up, it_detrain_up, it_entrain_dwn, it_detrain_dwn & - , it_uw_dp, it_vw_dp & - , it_uw_shall, it_vw_shall, it_uw_mid, it_vw_mid & - , it_wqt_flux, it_wthetal_flux, it_wthetav_flux, it_wql_flux & - , it_mf_deep, it_mf_congest, it_mf_shall, it_mf_midlev & - , it_dt_deep, it_dt_congest, it_dt_shall, it_dt_midlev & - , it_dq_deep, it_dq_congest, it_dq_shall, it_dq_midlev & - , it_du_deep, it_du_congest, it_du_shall, it_du_midlev & - , it_dv_deep, it_dv_congest, it_dv_shall, it_dv_midlev & - , ind_cape_reduced, cape_ts_used, it_ind_deep, it_ind_shall & - , it_w2p, it_dt_dd, it_dq_dd, it_du_dd, it_dv_dd, it_area_ud & - , it_area_dd, scm_convss_dg, l_scm_convss_dg & - , g_ccp, h_ccp, ccp_strength & - ) + nml_segment_size = min(conv_gr_segment_size,ncells) + num_seg = ceiling(real(ncells,r_um)/real(nml_segment_size,r_um)) + + do i = 1, num_seg + ii = (i-1)*nml_segment_size + 1 + seg_size = min(ncells, ii+nml_segment_size-1) - ii + 1 + + seg_num = map_wth(1,ii) ! Only used by debugging error message from UM + ! This is probably most useful to indicate + ! which column has a problem + + n_deep = 0 + if (iconv_deep > 0 ) then + do j = ii, ii+seg_size-1 + if (cumulus(j,1) .AND. .NOT. l_shallow(j,1) ) then + n_deep = n_deep + 1 + endif + end do + end if + + n_shallow = 0 + if (iconv_shallow > 0 ) then + do j = ii, ii+seg_size-1 + if (cumulus(j,1) .AND. l_shallow(j,1) ) then + n_shallow = n_shallow + 1 + endif + end do + end if + + n_congestus = 0 + do j = ii, ii+seg_size-1 + if (cumulus(j,1)) then + n_congestus = n_congestus + 1 ! as UM though not actually using scheme + end if + end do + + n_mid = 0 + do j = ii, ii+seg_size-1 + if (l_mid(j,1)) then + n_mid = n_mid + 1 + end if + end do + + call glue_conv_6a & + ( ncells, seg_size, n_conv_levels, n_wtrac, bl_levels & + , call_number, seg_num, theta_conv(ii,1,1), q_conv(ii,1,1) & + , qcl_conv(ii,1,1), qcf_conv(ii,1,1) & + , q_wtrac(ii,1,1), qcl_wtrac(ii,1,1), qcf_wtrac(ii,1,1) & + , cf_liquid_conv(ii,1,1), cf_frozen_conv(ii,1,1) & + , bulk_cf_conv(ii,1,1) & + , p_star(ii,1), land_sea_mask(ii,1) & + , u_conv(ii,1,1), v_conv(ii,1,1), w(ii,1,1) & + , tot_tracer(ii,1,1,1), dthbydt(ii,1,1), dqbydt(ii,1,1) & + , dqclbydt(ii,1,1), dqcfbydt(ii,1,1) & + , dcflbydt(ii,1,1), dcffbydt(ii,1,1), dbcfbydt(ii,1,1) & + , dubydt_p(ii,1,1), dvbydt_p(ii,1,1) & + , dqbydt_wtrac(ii,1,1), dqclbydt_wtrac(ii,1,1) & + , dqcfbydt_wtrac(ii,1,1) & + , it_conv_rain(ii,1), it_conv_snow(ii,1) & + , it_conv_rain_3d(ii,1,1), it_conv_snow_3d(ii,1,1) & + , rain_wtrac(ii,1), snow_wtrac(ii,1) & + , it_cca0_dp(ii,1,1), it_cca0_md(ii,1,1), it_cca0_sh(ii,1,1) & + , it_cca0(ii,1,1), it_ccb0(ii,1), it_cct0(ii,1) & + , it_cclwp0(ii,1), it_ccw0(ii,1,1) & + , it_lcbase0(ii,1), it_lctop(ii,1), it_lcca(ii,1) & + , it_cca(ii,1,1), it_ccb(ii,1), it_cct(ii,1), it_cclwp(ii,1) & + , it_ccw(ii,1,1), it_lcbase(ii,1) & + , it_cca_2d(ii,1), freeze_lev(ii,1) & + , it_dp_cfl_limited(ii,1), it_md_cfl_limited(ii,1) & + , it_mid_level(ii,1), it_kterm_deep(ii,1), it_kterm_shall(ii,1) & + , it_precip_dp(ii,1), it_precip_sh(ii,1) & + , it_precip_md(ii,1), it_precip_cg(ii,1) & + , it_wstar_dn(ii,1), it_wstar_up(ii,1) & + , it_mb1(ii,1), it_mb2(ii,1), it_cg_term(ii,1) & + , uw0(ii,1), vw0(ii,1), w_max(ii,1) & + , zlcl(ii,1), zlcl_uv(ii,1), tnuc_new(ii,1,1), tnuc_nlcl_um(ii,1) & + , zhpar(ii,1), entrain_coef(ii,1) & + , conv_prog_precip_conv(ii,1,1), conv_prog_flx(ii,1,1) & + , deep_flag(ii,1) & + , past_conv_ht(ii,1), it_cape_diluted(ii,1) & + , n_deep, n_congestus, n_shallow, n_mid & + , r_rho_levels(ii,1,1), r_theta_levels(ii,1,0) & + , rho_wet(ii,1,1), rho_wet_tq(ii,1,1), rho_dry(ii,1,1) & + , rho_dry_theta(ii,1,1), delta_smag(ii,1) & + , exner_rho_levels(ii,1,1), exner_rho_minus_one(ii,1,0) & + , exner_theta_levels(ii,1,0) & + , p_rho_minus_one(ii,1,0), p_theta_levels(ii,1,0) & + , z_theta(ii,1,1), z_rho(ii,1,1), timestep_conv & + , t1_sd(ii,1), q1_sd(ii,1), ntml(ii,1), ntpar(ii,1) & + , conv_type(ii,1), l_shallow(ii,1) & + , l_congestus(ii,1), l_mid(ii,1), cumulus(ii,1) & + , wstar(ii,1), wthvs(ii,1), delthvu(ii,1), ql_ad(ii,1) & + , qsat_lcl(ii,1), ftl(ii,1), fqw(ii,1) & + , l_tracer, ntra_fld, ntra_lev, n_cca_lev & + , l_calc_dxek , l_q_interact & + , it_up_flux_half(ii,1,1), it_up_flux(ii,1,1), it_dwn_flux(ii,1,1) & + , it_entrain_up(ii,1,1), it_detrain_up(ii,1,1) & + , it_entrain_dwn(ii,1,1), it_detrain_dwn(ii,1,1) & + , it_uw_dp(ii,1,1), it_vw_dp(ii,1,1) & + , it_uw_shall(ii,1,1), it_vw_shall(ii,1,1) & + , it_uw_mid(ii,1,1), it_vw_mid(ii,1,1) & + , it_wqt_flux(ii,1,1), it_wthetal_flux(ii,1,1) & + , it_wthetav_flux(ii,1,1), it_wql_flux(ii,1,1) & + , it_mf_deep(ii,1,1), it_mf_congest(ii,1,1) & + , it_mf_shall(ii,1,1), it_mf_midlev(ii,1,1) & + , it_dt_deep(ii,1,1), it_dt_congest(ii,1,1) & + , it_dt_shall(ii,1,1), it_dt_midlev(ii,1,1) & + , it_dq_deep(ii,1,1), it_dq_congest(ii,1,1) & + , it_dq_shall(ii,1,1), it_dq_midlev(ii,1,1) & + , it_du_deep(ii,1,1), it_du_congest(ii,1,1) & + , it_du_shall(ii,1,1), it_du_midlev(ii,1,1) & + , it_dv_deep(ii,1,1), it_dv_congest(ii,1,1) & + , it_dv_shall(ii,1,1), it_dv_midlev(ii,1,1) & + , ind_cape_reduced(ii,1), cape_ts_used(ii,1) & + , it_ind_deep(ii,1), it_ind_shall(ii,1) & + , it_w2p(ii,1,1), it_dt_dd(ii,1,1), it_dq_dd(ii,1,1) & + , it_du_dd(ii,1,1), it_dv_dd(ii,1,1) & + , it_area_ud(ii,1,1), it_area_dd(ii,1,1) & + , scm_convss_dg, l_scm_convss_dg & + , g_ccp(ii,1), h_ccp(ii,1), ccp_strength(ii,1) & + ) + end do ! i -> num_seg ! Mid-level convection only possible on subsequent sub-steps if ! occurs on first step or column is diagnosed as cumulus - l_mid(1,1) = it_mid_level(1,1) .or. cumulus(1,1) + do i = 1, ncells + l_mid(i,1) = it_mid_level(i,1) .or. cumulus(i,1) + end do ! Update cloud info from substep ! Highest convective layer properties - diagnostic !------------------------------------ ! max cct across total number of calls to convection ! Note that diagnostic is a real not an integer - cct(1,1) = max( cct(1,1),it_cct(1,1)) - ! min ccb across total number of calls to convection - ! excluding ccb=0 - if (ccb(1,1) > 0 .AND. it_ccb(1,1) > 0) then - ccb(1,1) = min(ccb(1,1),it_ccb(1,1)) - else - ccb(1,1) = max(ccb(1,1),it_ccb(1,1)) - end if + do i = 1, ncells + cct(i,1) = max( cct(i,1),it_cct(i,1)) + ! min ccb across total number of calls to convection + ! excluding ccb=0 + if (ccb(i,1) > 0 .AND. it_ccb(i,1) > 0) then + ccb(i,1) = min(ccb(i,1),it_ccb(i,1)) + else + ccb(i,1) = max(ccb(i,1),it_ccb(i,1)) + end if + end do ! Lowest convective layer properties !------------------------------------ ! max lctop across total number of calls to convection - lctop(1,1) = max(lctop(1,1),it_lctop(1,1)) + do i = 1, ncells + lctop(i,1) = max(lctop(i,1),it_lctop(i,1)) - ! min lcbase across total number of calls to convection - ! excluding lcbase=0 - if (lcbase(1,1) > 0 .AND. it_lcbase(1,1) > 0) then - lcbase(1,1) = min(lcbase(1,1), it_lcbase(1,1)) - else - lcbase(1,1) = max(lcbase(1,1), it_lcbase(1,1)) - end if + ! min lcbase across total number of calls to convection + ! excluding lcbase=0 + if (lcbase(i,1) > 0 .AND. it_lcbase(i,1) > 0) then + lcbase(i,1) = min(lcbase(i,1), it_lcbase(i,1)) + else + lcbase(i,1) = max(lcbase(i,1), it_lcbase(i,1)) + end if + end do do k=1, nlayers - ccw_3d(1,1,k) = ccw_3d(1,1,k) + one_over_conv_calls*it_ccw0(1,1,k) - cca_3d(1,1,k) = cca_3d(1,1,k) + one_over_conv_calls*it_cca0(1,1,k) - ! Assuming lccrad = .true. - cca_3d(1,1,k) = min(cca_3d(1,1,k), 1.0_r_um) + do i = 1, ncells + ccw_3d(i,1,k) = ccw_3d(i,1,k) + one_over_conv_calls*it_ccw0(i,1,k) + cca_3d(i,1,k) = cca_3d(i,1,k) + one_over_conv_calls*it_cca0(i,1,k) + ! Assuming lccrad = .true. + cca_3d(i,1,k) = min(cca_3d(i,1,k), 1.0_r_um) + end do end do ! single level convection diagnostics - conv_rain(map_2d(1)) = conv_rain(map_2d(1))+ & - it_conv_rain(1,1) *one_over_conv_calls - conv_snow(map_2d(1)) = conv_snow(map_2d(1))+ & - it_conv_snow(1,1) *one_over_conv_calls - cca_2d(map_2d(1)) = cca_2d(map_2d(1))+ & - it_cca_2d(1,1) *one_over_conv_calls - cape_diluted(map_2d(1)) = cape_diluted(map_2d(1)) + & - it_cape_diluted(1,1)*one_over_conv_calls + do i = 1, ncells + conv_rain(map_2d(1,i)) = conv_rain(map_2d(1,i))+ & + it_conv_rain(i,1) *one_over_conv_calls + conv_snow(map_2d(1,i)) = conv_snow(map_2d(1,i))+ & + it_conv_snow(i,1) *one_over_conv_calls + cca_2d(map_2d(1,i)) = cca_2d(map_2d(1,i))+ & + it_cca_2d(i,1) *one_over_conv_calls + cape_diluted(map_2d(1,i)) = cape_diluted(map_2d(1,i)) + & + it_cape_diluted(i,1)*one_over_conv_calls + end do if (outer == outer_iterations) then if (.not. associated(lowest_cca_2d, empty_real_data) ) then - lowest_cca_2d(map_2d(1)) = lowest_cca_2d(map_2d(1)) + & - it_lcca(1,1)*one_over_conv_calls + do i = 1, ncells + lowest_cca_2d(map_2d(1,i)) = lowest_cca_2d(map_2d(1,i)) + & + it_lcca(i,1)*one_over_conv_calls + end do end if if (.not. associated(deep_in_col, empty_real_data) ) then - deep_in_col(map_2d(1)) = deep_in_col(map_2d(1)) + & - it_ind_deep(1,1)*one_over_conv_calls + do i = 1, ncells + deep_in_col(map_2d(1,i)) = deep_in_col(map_2d(1,i)) + & + it_ind_deep(i,1)*one_over_conv_calls + end do end if if (.not. associated(shallow_in_col, empty_real_data) ) then - shallow_in_col(map_2d(1)) = shallow_in_col(map_2d(1)) + & - it_ind_shall(1,1)*one_over_conv_calls + do i = 1, ncells + shallow_in_col(map_2d(1,i)) = shallow_in_col(map_2d(1,i)) + & + it_ind_shall(i,1)*one_over_conv_calls + end do end if if (.not. associated(mid_in_col, empty_real_data) ) then - if (it_mid_level(1,1)) then - mid_in_col(map_2d(1)) = mid_in_col(map_2d(1)) + one_over_conv_calls - end if + do i = 1, ncells + if (it_mid_level(i,1)) then + mid_in_col(map_2d(1,i)) = mid_in_col(map_2d(1,i)) + one_over_conv_calls + end if + end do end if if (.not. associated(freeze_level, empty_real_data) ) then - freeze_level(map_2d(1)) = freeze_level(map_2d(1)) + & - real(freeze_lev(1,1)) *one_over_conv_calls + do i = 1, ncells + freeze_level(map_2d(1,i)) = freeze_level(map_2d(1,i)) + & + real(freeze_lev(i,1)) *one_over_conv_calls + end do end if if (.not. associated(deep_prec, empty_real_data) ) then - deep_prec(map_2d(1)) = deep_prec(map_2d(1)) + & - it_precip_dp(1,1) *one_over_conv_calls + do i = 1, ncells + deep_prec(map_2d(1,i)) = deep_prec(map_2d(1,i)) + & + it_precip_dp(i,1) *one_over_conv_calls + end do end if if (.not. associated(shallow_prec, empty_real_data) ) then - shallow_prec(map_2d(1)) = shallow_prec(map_2d(1)) + & - it_precip_sh(1,1) *one_over_conv_calls + do i = 1, ncells + shallow_prec(map_2d(1,i)) = shallow_prec(map_2d(1,i)) + & + it_precip_sh(i,1) *one_over_conv_calls + end do end if if (.not. associated(mid_prec, empty_real_data) ) then - mid_prec(map_2d(1)) = mid_prec(map_2d(1)) + & - it_precip_md(1,1) *one_over_conv_calls + do i = 1, ncells + mid_prec(map_2d(1,i)) = mid_prec(map_2d(1,i)) + & + it_precip_md(i,1) *one_over_conv_calls + end do end if if (.not. associated(deep_term, empty_real_data) ) then - deep_term(map_2d(1)) = deep_term(map_2d(1)) + & - real(it_kterm_deep(1,1)) *one_over_conv_calls + do i = 1, ncells + deep_term(map_2d(1,i)) = deep_term(map_2d(1,i)) + & + real(it_kterm_deep(i,1)) *one_over_conv_calls + end do end if if (.not. associated(cape_timescale, empty_real_data) ) then - cape_timescale(map_2d(1)) =cape_timescale(map_2d(1)) + & - cape_ts_used(1,1) *one_over_conv_calls + do i = 1, ncells + cape_timescale(map_2d(1,i)) =cape_timescale(map_2d(1,i)) + & + cape_ts_used(i,1) *one_over_conv_calls + end do end if if (.not. associated(deep_cfl_limited, empty_real_data) ) then - deep_cfl_limited(map_2d(1)) = deep_cfl_limited(map_2d(1)) + & - it_dp_cfl_limited(1,1) *one_over_conv_calls + do i = 1, ncells + deep_cfl_limited(map_2d(1,i)) = deep_cfl_limited(map_2d(1,i)) + & + it_dp_cfl_limited(i,1) *one_over_conv_calls + end do end if if (.not. associated(mid_cfl_limited, empty_real_data) ) then - mid_cfl_limited(map_2d(1)) = mid_cfl_limited(map_2d(1)) + & - it_md_cfl_limited(1,1) *one_over_conv_calls + do i = 1, ncells + mid_cfl_limited(map_2d(1,i)) = mid_cfl_limited(map_2d(1,i)) + & + it_md_cfl_limited(i,1) *one_over_conv_calls + end do end if ! Frequency of deep convection terminating on level k if (.not. associated(deep_tops, empty_real_data) ) then - if (it_ind_deep(1,1) == 1.0_r_um) then - k = it_kterm_deep(1,1) - if (k > 0) then ! in case still get a zero value - deep_tops(map_wth(1)+k) = deep_tops(map_wth(1)+k) + one_over_conv_calls + k = 0 ! dummy initialisation for psyclone firstprivate bug and cray compiler + do i = 1, ncells + if (it_ind_deep(i,1) == 1.0_r_um) then + k = it_kterm_deep(i,1) + if (k > 0) then ! in case still get a zero value + deep_tops(map_wth(1,i)+k) = deep_tops(map_wth(1,i)+k) + one_over_conv_calls + end if end if - end if + end do end if end if ! outer_iterations ! update input fields *_conv for next substep do k = 1, n_conv_levels - theta_conv(1,1,k) = theta_conv(1,1,k) & - + dthbydt(1,1,k) * timestep_conv - q_conv(1,1,k) = q_conv(1,1,k) & - + dqbydt(1,1,k) * timestep_conv - qcl_conv(1,1,k) = qcl_conv(1,1,k) & - +(dqclbydt(1,1,k) * timestep_conv) - qcf_conv(1,1,k) = qcf_conv(1,1,k) & - +(dqcfbydt(1,1,k) * timestep_conv) - cf_liquid_conv(1,1,k) = cf_liquid_conv(1,1,k) & - +(dcflbydt(1,1,k) * timestep_conv) - cf_frozen_conv(1,1,k) = cf_frozen_conv(1,1,k) & - + (dcffbydt(1,1,k) * timestep_conv) - bulk_cf_conv(1,1,k) = bulk_cf_conv(1,1,k) & - +(dbcfbydt(1,1,k) * timestep_conv) - dtheta_conv(1,1,k) = dtheta_conv(1,1,k) & - + dthbydt(1,1,k) * timestep_conv - dt_conv(map_wth(1) + k) = dt_conv(map_wth(1) + k) & - + dthbydt(1,1,k) * timestep_conv & - * exner_theta_levels(1,1,k) - dmv_conv(map_wth(1) + k) = dmv_conv(map_wth(1) + k) & - + dqbydt(1,1,k) * timestep_conv - dmcl_conv(map_wth(1) + k) = dmcl_conv(map_wth(1) + k) & - + dqclbydt(1,1,k) * timestep_conv - dms_conv(map_wth(1) + k) = dms_conv(map_wth(1) + k) & - + dqcfbydt(1,1,k) * timestep_conv - - ! Update diagnostics - massflux_up(map_wth(1) + k) = massflux_up(map_wth(1) + k) + & - it_up_flux(1,1,k)*one_over_conv_calls - massflux_down(map_wth(1) + k) = massflux_down(map_wth(1) + k)+ & - it_dwn_flux(1,1,k)*one_over_conv_calls - - conv_rain_3d(map_wth(1) + k) = conv_rain_3d(map_wth(1) + k) + & - it_conv_rain_3d(1,1,k) * & - one_over_conv_calls - conv_snow_3d(map_wth(1) + k) = conv_snow_3d(map_wth(1) + k) + & - it_conv_snow_3d(1,1,k) * & - one_over_conv_calls + do i = 1, ncells + theta_conv(i,1,k) = theta_conv(i,1,k) & + + dthbydt(i,1,k) * timestep_conv + q_conv(i,1,k) = q_conv(i,1,k) & + + dqbydt(i,1,k) * timestep_conv + qcl_conv(i,1,k) = qcl_conv(i,1,k) & + +(dqclbydt(i,1,k) * timestep_conv) + qcf_conv(i,1,k) = qcf_conv(i,1,k) & + +(dqcfbydt(i,1,k) * timestep_conv) + cf_liquid_conv(i,1,k) = cf_liquid_conv(i,1,k) & + +(dcflbydt(i,1,k) * timestep_conv) + cf_frozen_conv(i,1,k) = cf_frozen_conv(i,1,k) & + + (dcffbydt(i,1,k) * timestep_conv) + bulk_cf_conv(i,1,k) = bulk_cf_conv(i,1,k) & + +(dbcfbydt(i,1,k) * timestep_conv) + dtheta_conv(i,1,k) = dtheta_conv(i,1,k) & + + dthbydt(i,1,k) * timestep_conv + dt_conv(map_wth(1,i) + k) = dt_conv(map_wth(1,i) + k) & + + dthbydt(i,1,k) * timestep_conv & + * exner_theta_levels(i,1,k) + dmv_conv(map_wth(1,i) + k) = dmv_conv(map_wth(1,i) + k) & + + dqbydt(i,1,k) * timestep_conv + dmcl_conv(map_wth(1,i) + k) = dmcl_conv(map_wth(1,i) + k) & + + dqclbydt(i,1,k) * timestep_conv + dms_conv(map_wth(1,i) + k) = dms_conv(map_wth(1,i) + k) & + + dqcfbydt(i,1,k) * timestep_conv + + ! Update diagnostics + massflux_up(map_wth(1,i) + k) = massflux_up(map_wth(1,i) + k) + & + it_up_flux(i,1,k)*one_over_conv_calls + massflux_down(map_wth(1,i) + k) = massflux_down(map_wth(1,i) + k)+ & + it_dwn_flux(i,1,k)*one_over_conv_calls + + conv_rain_3d(map_wth(1,i) + k) = conv_rain_3d(map_wth(1,i) + k) + & + it_conv_rain_3d(i,1,k) * & + one_over_conv_calls + conv_snow_3d(map_wth(1,i) + k) = conv_snow_3d(map_wth(1,i) + k) + & + it_conv_snow_3d(i,1,k) * & + one_over_conv_calls + end do end do - ! Update optional diagnostics + ! Update optional diagnostics if (outer == outer_iterations) then if (.not. associated(entrain_up, empty_real_data) ) then do k = 1, n_conv_levels - entrain_up(map_wth(1) + k) = entrain_up(map_wth(1) + k) + & - it_entrain_up(1,1,k)*one_over_conv_calls + do i = 1, ncells + entrain_up(map_wth(1,i) + k) = entrain_up(map_wth(1,i) + k) + & + it_entrain_up(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(entrain_down, empty_real_data) ) then do k = 1, n_conv_levels - entrain_down(map_wth(1) + k) = entrain_down(map_wth(1) + k) + & - it_entrain_dwn(1,1,k)*one_over_conv_calls + do i = 1, ncells + entrain_down(map_wth(1,i) + k) = entrain_down(map_wth(1,i) + k) + & + it_entrain_dwn(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(detrain_up, empty_real_data) ) then do k = 1, n_conv_levels - detrain_up(map_wth(1) + k) = detrain_up(map_wth(1) + k) + & - it_detrain_up(1,1,k)*one_over_conv_calls + do i = 1, ncells + detrain_up(map_wth(1,i) + k) = detrain_up(map_wth(1,i) + k) + & + it_detrain_up(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(detrain_down, empty_real_data) ) then do k = 1, n_conv_levels - detrain_down(map_wth(1) + k) = detrain_down(map_wth(1) + k) + & - it_detrain_dwn(1,1,k)*one_over_conv_calls + do i = 1, ncells + detrain_down(map_wth(1,i) + k) = detrain_down(map_wth(1,i) + k) + & + it_detrain_dwn(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(dd_dt, empty_real_data) ) then do k = 1, n_conv_levels - dd_dt(map_wth(1) + k) = dd_dt(map_wth(1) + k) + & - it_dt_dd(1,1,k)*one_over_conv_calls + do i = 1, ncells + dd_dt(map_wth(1,i) + k) = dd_dt(map_wth(1,i) + k) + & + it_dt_dd(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(dd_dq, empty_real_data) ) then do k = 1, n_conv_levels - dd_dq(map_wth(1) + k) = dd_dq(map_wth(1) + k) + & - it_dq_dd(1,1,k)*one_over_conv_calls + do i = 1, ncells + dd_dq(map_wth(1,i) + k) = dd_dq(map_wth(1,i) + k) + & + it_dq_dd(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(deep_massflux, empty_real_data) ) then do k = 1, n_conv_levels - deep_massflux(map_wth(1) + k) = deep_massflux(map_wth(1) + k) + & - it_mf_deep(1,1,k)*one_over_conv_calls + do i = 1, ncells + deep_massflux(map_wth(1,i) + k) = deep_massflux(map_wth(1,i) + k) + & + it_mf_deep(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(deep_dt, empty_real_data) ) then do k = 1, n_conv_levels - deep_dt(map_wth(1) + k) = deep_dt(map_wth(1) + k) + & - it_dt_deep(1,1,k)*one_over_conv_calls + do i = 1, ncells + deep_dt(map_wth(1,i) + k) = deep_dt(map_wth(1,i) + k) + & + it_dt_deep(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(deep_dq, empty_real_data) ) then do k = 1, n_conv_levels - deep_dq(map_wth(1) + k) = deep_dq(map_wth(1) + k) + & - it_dq_deep(1,1,k)*one_over_conv_calls + do i = 1, ncells + deep_dq(map_wth(1,i) + k) = deep_dq(map_wth(1,i) + k) + & + it_dq_deep(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(shallow_massflux, empty_real_data) ) then do k = 1, n_conv_levels - shallow_massflux(map_wth(1) + k) = shallow_massflux(map_wth(1) + k) + & - it_mf_shall(1,1,k)*one_over_conv_calls + do i = 1, ncells + shallow_massflux(map_wth(1,i) + k) = shallow_massflux(map_wth(1,i) + k) + & + it_mf_shall(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(shallow_dt, empty_real_data) ) then do k = 1, n_conv_levels - shallow_dt(map_wth(1) + k) = shallow_dt(map_wth(1) + k) + & - it_dt_shall(1,1,k)*one_over_conv_calls + do i = 1, ncells + shallow_dt(map_wth(1,i) + k) = shallow_dt(map_wth(1,i) + k) + & + it_dt_shall(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(shallow_dq, empty_real_data) ) then do k = 1, n_conv_levels - shallow_dq(map_wth(1) + k) = shallow_dq(map_wth(1) + k) + & - it_dq_shall(1,1,k)*one_over_conv_calls + do i = 1, ncells + shallow_dq(map_wth(1,i) + k) = shallow_dq(map_wth(1,i) + k) + & + it_dq_shall(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(mid_massflux, empty_real_data) ) then do k = 1, n_conv_levels - mid_massflux(map_wth(1) + k) = mid_massflux(map_wth(1) + k) + & - it_mf_midlev(1,1,k)*one_over_conv_calls + do i = 1, ncells + mid_massflux(map_wth(1,i) + k) = mid_massflux(map_wth(1,i) + k) + & + it_mf_midlev(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(mid_dt, empty_real_data) ) then do k = 1, n_conv_levels - mid_dt(map_wth(1) + k) = mid_dt(map_wth(1) + k) + & - it_dt_midlev(1,1,k)*one_over_conv_calls + do i = 1, ncells + mid_dt(map_wth(1,i) + k) = mid_dt(map_wth(1,i) + k) + & + it_dt_midlev(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(mid_dq, empty_real_data) ) then do k = 1, n_conv_levels - mid_dq(map_wth(1) + k) = mid_dq(map_wth(1) + k) + & - it_dq_midlev(1,1,k)*one_over_conv_calls + do i = 1, ncells + mid_dq(map_wth(1,i) + k) = mid_dq(map_wth(1,i) + k) + & + it_dq_midlev(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(cca_unadjusted, empty_real_data) ) then do k = 1, n_conv_levels - cca_unadjusted(map_wth(1) + k) = cca_unadjusted(map_wth(1) + k) + & - it_cca(1,1,k)*one_over_conv_calls + do i = 1, ncells + cca_unadjusted(map_wth(1,i) + k) = cca_unadjusted(map_wth(1,i) + k) + & + it_cca(i,1,k)*one_over_conv_calls + end do end do end if if (.not. associated(massflux_up_half, empty_real_data) ) then do k = 1, n_conv_levels - massflux_up_half(map_w3(1) + k-1) = massflux_up_half(map_w3(1) + k-1) +& - it_up_flux_half(1,1,k)*one_over_conv_calls + do i = 1, ncells + massflux_up_half(map_w3(1,i) + k-1) = massflux_up_half(map_w3(1,i) + k-1) +& + it_up_flux_half(i,1,k)*one_over_conv_calls + end do end do end if end if ! outer_iterations if (l_mom) then do k = 1, n_conv_levels - u_conv(1,1,k) = u_conv(1,1,k) + dubydt_p(1,1,k) * timestep_conv - v_conv(1,1,k) = v_conv(1,1,k) + dvbydt_p(1,1,k) * timestep_conv - ! total increments - du_conv(map_w3(1) + k -1) = du_conv(map_w3(1) + k -1) + dubydt_p(1,1,k) * timestep_conv - dv_conv(map_w3(1) + k -1) = dv_conv(map_w3(1) + k -1) + dvbydt_p(1,1,k) * timestep_conv + do i = 1, ncells + u_conv(i,1,k) = u_conv(i,1,k) + dubydt_p(i,1,k) * timestep_conv + v_conv(i,1,k) = v_conv(i,1,k) + dvbydt_p(i,1,k) * timestep_conv + ! total increments + du_conv(map_w3(1,i) + k -1) = du_conv(map_w3(1,i) + k -1) + dubydt_p(i,1,k) * timestep_conv + dv_conv(map_w3(1,i) + k -1) = dv_conv(map_w3(1,i) + k -1) + dvbydt_p(i,1,k) * timestep_conv + end do end do end if !l_mom @@ -2142,7 +2547,9 @@ subroutine conv_gr_code(nlayers, & if (l_safe_conv) then do k = 1, n_conv_levels - dmv_conv(map_wth(1) + k) = dmv_conv(map_wth(1) + k) + dq_add(1,1,k) + do i = 1, ncells + dmv_conv(map_wth(1,i) + k) = dmv_conv(map_wth(1,i) + k) + dq_add(i,1,k) + end do end do end if @@ -2150,51 +2557,70 @@ subroutine conv_gr_code(nlayers, & if (l_conv_prog_precip .and. outer == outer_iterations) then decay_amount = timestep / tau_conv_prog_precip theta_inc_threshold = dthetadt_conv_active_threshold * timestep_conv - tot_conv_precip_2d(1,1) = MAX(conv_rain(map_2d(1)) + & - conv_snow(map_2d(1)), & - conv_prog_precip_min_threshold ) + do i = 1, ncells + tot_conv_precip_2d(i,1) = MAX(conv_rain(map_2d(1,i)) + & + conv_snow(map_2d(1,i)), & + conv_prog_precip_min_threshold ) + end do + conv_active = 0.0_r_um ! dummy initialisation for psyclone firstprivate bug and cray compiler do k = 1, n_conv_levels - if (abs(dtheta_conv(1,1,k)) > theta_inc_threshold) then - conv_active = 1.0_r_um - else - conv_active = 0.0_r_um - end if - conv_prog_precip(map_wth(1) + k) & - = decay_amount * tot_conv_precip_2d(1,1) * conv_active & - + (1.0_r_def - decay_amount) * conv_prog_precip(map_wth(1) + k) + do i = 1, ncells + if (abs(dtheta_conv(i,1,k)) > theta_inc_threshold) then + conv_active = 1.0_r_um + else + conv_active = 0.0_r_um + end if + conv_prog_precip(map_wth(1,i) + k) & + = decay_amount * tot_conv_precip_2d(i,1) * conv_active & + + (1.0_r_def - decay_amount) * conv_prog_precip(map_wth(1,i) + k) + end do + end do + do i = 1, ncells + conv_prog_precip(map_wth(1,i) + 0) = conv_prog_precip(map_wth(1,i) + 1) end do - conv_prog_precip(map_wth(1) + 0) = conv_prog_precip(map_wth(1) + 1) end if if (l_conv_prog_dtheta) then decay_amount = timestep / tau_conv_prog_dtheta do k = 1, n_conv_levels - dt_conv(map_wth(1) + k) = (decay_amount * dtheta_conv(1,1,k) & - + (1.0_r_def - decay_amount) * conv_prog_dtheta(map_wth(1) + k))& - * exner_in_wth(map_wth(1) + k) + do i = 1, ncells + dt_conv(map_wth(1,i) + k) = (decay_amount * dtheta_conv(i,1,k) & + + (1.0_r_def - decay_amount) * conv_prog_dtheta(map_wth(1,i) + k)) & + * exner_in_wth(map_wth(1,i) + k) + end do end do if (outer == outer_iterations) then do k = 1, n_conv_levels - conv_prog_dtheta(map_wth(1) + k) = dt_conv(map_wth(1) + k) & - / exner_in_wth(map_wth(1) + k) + do i = 1, ncells + conv_prog_dtheta(map_wth(1,i) + k) = dt_conv(map_wth(1,i) + k) & + / exner_in_wth(map_wth(1,i) + k) + end do + end do + do i = 1, ncells + conv_prog_dtheta(map_wth(1,i) + 0) = conv_prog_dtheta(map_wth(1,i) + 1) end do - conv_prog_dtheta(map_wth(1) + 0) = conv_prog_dtheta(map_wth(1) + 1) end if end if if (l_conv_prog_dq) then decay_amount = timestep / tau_conv_prog_dq do k = 1, n_conv_levels - dmv_conv(map_wth(1) + k) = decay_amount * dmv_conv(map_wth(1) + k) & - + (1.0_r_def - decay_amount) * conv_prog_dmv(map_wth(1) + k) + do i = 1, ncells + dmv_conv(map_wth(1,i) + k) = decay_amount * dmv_conv(map_wth(1,i) + k) & + + (1.0_r_def - decay_amount) * conv_prog_dmv(map_wth(1,i) + k) + end do end do if (outer == outer_iterations) then do k = 1, n_conv_levels - conv_prog_dmv(map_wth(1) + k) = dmv_conv(map_wth(1) + k) + do i = 1, ncells + conv_prog_dmv(map_wth(1,i) + k) = dmv_conv(map_wth(1,i) + k) + end do + end do + do i = 1, ncells + conv_prog_dmv(map_wth(1,i) + 0) = conv_prog_dmv(map_wth(1,i) + 1) end do - conv_prog_dmv(map_wth(1) + 0) = conv_prog_dmv(map_wth(1) + 1) end if end if @@ -2204,597 +2630,853 @@ subroutine conv_gr_code(nlayers, & ! In-cloud condensate amounts above 2.0e-3 lead to ! cloud fraction being increased (up to a value of 1.0) + orig_value = 0.0_r_um ! dummy initialisation for psyclone firstprivate bug and cray compiler do k = 1, n_conv_levels - ! Liquid cloud fraction - if (cf_liquid_conv(1,1,k) > 0.0_r_um) then - if ( (qcl_conv(1,1,k)/cf_liquid_conv(1,1,k) ) > 2.0e-3_r_um ) then - orig_value = cf_liquid_conv(1,1,k) - cf_liquid_conv(1,1,k) = min(1.0_r_um,qcl_conv(1,1,k)/2.0e-3_r_um) - bulk_cf_conv(1,1,k) = bulk_cf_conv(1,1,k) & - + cf_liquid_conv(1,1,k) - orig_value + do i = 1, ncells + ! Liquid cloud fraction + if (cf_liquid_conv(i,1,k) > 0.0_r_um) then + if ( (qcl_conv(i,1,k)/cf_liquid_conv(i,1,k) ) > 2.0e-3_r_um ) then + orig_value = cf_liquid_conv(i,1,k) + cf_liquid_conv(i,1,k) = min(1.0_r_um,qcl_conv(i,1,k)/2.0e-3_r_um) + bulk_cf_conv(i,1,k) = bulk_cf_conv(i,1,k) & + + cf_liquid_conv(i,1,k) - orig_value + end if end if - end if - ! Ice cloud fraction - if (cf_frozen_conv(1,1,k) > 0.0_r_um) then - if ( (qcf_conv(1,1,k)/cf_frozen_conv(1,1,k)) > 2.0e-3_r_um ) then - orig_value = cf_frozen_conv(1,1,k) - cf_frozen_conv(1,1,k) = min(1.0_r_um,qcf_conv(1,1,k)/2.0e-3_r_um) - bulk_cf_conv(1,1,k) = bulk_cf_conv(1,1,k) & - + cf_frozen_conv(1,1,k) - orig_value + ! Ice cloud fraction + if (cf_frozen_conv(i,1,k) > 0.0_r_um) then + if ( (qcf_conv(i,1,k)/cf_frozen_conv(i,1,k)) > 2.0e-3_r_um ) then + orig_value = cf_frozen_conv(i,1,k) + cf_frozen_conv(i,1,k) = min(1.0_r_um,qcf_conv(i,1,k)/2.0e-3_r_um) + bulk_cf_conv(i,1,k) = bulk_cf_conv(i,1,k) & + + cf_frozen_conv(i,1,k) - orig_value + end if end if - end if + end do end do ! Store cloud fraction increments for adding on later if using PC2 do k = 1, n_conv_levels - dcfl_conv(map_wth(1) + k) = cf_liquid_conv(1,1,k) - cf_liq(map_wth(1) + k) - dcff_conv(map_wth(1) + k) = cf_frozen_conv(1,1,k) - cf_ice(map_wth(1) + k) - dbcf_conv(map_wth(1) + k) = bulk_cf_conv(1,1,k) - cf_bulk(map_wth(1) + k) + do i = 1, ncells + dcfl_conv(map_wth(1,i) + k) = cf_liquid_conv(i,1,k) - cf_liq(map_wth(1,i) + k) + dcff_conv(map_wth(1,i) + k) = cf_frozen_conv(i,1,k) - cf_ice(map_wth(1,i) + k) + dbcf_conv(map_wth(1,i) + k) = bulk_cf_conv(i,1,k) - cf_bulk(map_wth(1,i) + k) + end do + end do + do i = 1, ncells + dcfl_conv(map_wth(1,i) + 0) = dcfl_conv(map_wth(1,i) + 1) + dcff_conv(map_wth(1,i) + 0) = dcff_conv(map_wth(1,i) + 1) + dbcf_conv(map_wth(1,i) + 0) = dbcf_conv(map_wth(1,i) + 1) end do - dcfl_conv(map_wth(1) + 0) = dcfl_conv(map_wth(1) + 1) - dcff_conv(map_wth(1) + 0) = dcff_conv(map_wth(1) + 1) - dbcf_conv(map_wth(1) + 0) = dbcf_conv(map_wth(1) + 1) ! Set level 0 increment such that theta increment will equal level 1 - dt_conv (map_wth(1) + 0) = dt_conv (map_wth(1) + 1) & - * exner_in_wth(map_wth(1) + 0) & - / exner_in_wth(map_wth(1) + 1) - dmv_conv (map_wth(1) + 0) = dmv_conv (map_wth(1) + 1) - dmcl_conv(map_wth(1) + 0) = dmcl_conv(map_wth(1) + 1) - dms_conv(map_wth(1) + 0) = dms_conv(map_wth(1) + 1) + do i = 1, ncells + dt_conv (map_wth(1,i) + 0) = dt_conv (map_wth(1,i) + 1) & + * exner_in_wth(map_wth(1,i) + 0) & + / exner_in_wth(map_wth(1,i) + 1) + dmv_conv (map_wth(1,i) + 0) = dmv_conv (map_wth(1,i) + 1) + dmcl_conv(map_wth(1,i) + 0) = dmcl_conv(map_wth(1,i) + 1) + dms_conv(map_wth(1,i) + 0) = dms_conv(map_wth(1,i) + 1) + end do ! Store convective downdraught mass fluxes at cloud base ! if required for surface exchange. if (srf_ex_cnv_gust == ip_srfexwithcnv) then - if (ccb(1,1) > 0) then - dd_mf_cb(map_2d(1))=massflux_down( map_wth(1) + ccb(1,1)) - else - dd_mf_cb(map_2d(1))=0.0_r_def - end if + do i = 1, ncells + if (ccb(i,1) > 0) then + dd_mf_cb(map_2d(1,i)) = massflux_down( map_wth(1,i) + ccb(i,1)) + else + dd_mf_cb(map_2d(1,i)) = 0.0_r_def + end if + end do end if ! copy convective cloud fraction into prognostic array do k = 1, n_conv_levels - cca(map_wth(1) + k) = min(cca_3d(1,1,k), 1.0_r_um) - ccw(map_wth(1) + k) = ccw_3d(1,1,k) + do i = 1, ncells + cca(map_wth(1,i) + k) = min(cca_3d(i,1,k), 1.0_r_um) + ccw(map_wth(1,i) + k) = ccw_3d(i,1,k) + end do end do if (outer == outer_iterations) then ! Copy integers into real diagnostic arrays - if (.not. associated(cv_top, empty_real_data) ) then - cv_top(map_2d(1)) = real(cct(1,1)) + if (.not. associated(cv_top, empty_real_data) ) then + do i = 1, ncells + cv_top(map_2d(1,i)) = real(cct(i,1)) + end do end if if (.not. associated(cv_base, empty_real_data) ) then - cv_base(map_2d(1)) = real(ccb(1,1)) + do i = 1, ncells + cv_base(map_2d(1,i)) = real(ccb(i,1)) + end do end if if (.not. associated(lowest_cv_top, empty_real_data) ) then - lowest_cv_top(map_2d(1)) = real(lctop(1,1)) + do i = 1, ncells + lowest_cv_top(map_2d(1,i)) = real(lctop(i,1)) + end do end if if (.not. associated(lowest_cv_base, empty_real_data) ) then - lowest_cv_base(map_2d(1)) = real(lcbase(1,1)) + do i = 1, ncells + lowest_cv_base(map_2d(1,i)) = real(lcbase(i,1)) + end do end if ! pressure at cv top/base if (.not. associated(pres_cv_top, empty_real_data) ) then - if (cct(1,1) > 0) then - pres_cv_top(map_2d(1)) = p_rho_levels(1,1,cct(1,1)) - else - pres_cv_top(map_2d(1)) = 0.0_r_def - end if + do i = 1, ncells + if (cct(i,1) > 0) then + pres_cv_top(map_2d(1,i)) = p_rho_levels(i,1,cct(i,1)) + else + pres_cv_top(map_2d(1,i)) = 0.0_r_def + end if + end do end if if (.not. associated(pres_cv_base, empty_real_data) ) then - if (ccb(1,1) > 0) then - pres_cv_base(map_2d(1)) = p_rho_levels(1,1,ccb(1,1)) - else - pres_cv_base(map_2d(1))= 0.0_r_def - end if + do i = 1, ncells + if (ccb(i,1) > 0) then + pres_cv_base(map_2d(1,i)) = p_rho_levels(i,1,ccb(i,1)) + else + pres_cv_base(map_2d(1,i))= 0.0_r_def + end if + end do end if ! pressure at lowest cv top/base if (.not. associated(pres_lowest_cv_top, empty_real_data) ) then - if (lctop(1,1) > 0) then - pres_lowest_cv_top(map_2d(1)) = p_rho_levels(1,1,lctop(1,1)) - else - pres_lowest_cv_top(map_2d(1)) = 0.0_r_def - end if + do i = 1, ncells + if (lctop(i,1) > 0) then + pres_lowest_cv_top(map_2d(1,i)) = p_rho_levels(i,1,lctop(i,1)) + else + pres_lowest_cv_top(map_2d(1,i)) = 0.0_r_def + end if + end do end if if (.not. associated(pres_lowest_cv_base, empty_real_data) ) then - if (lcbase(1,1) > 0) then - pres_lowest_cv_base(map_2d(1)) = p_rho_levels(1,1,lcbase(1,1)) - else - pres_lowest_cv_base(map_2d(1))= 0.0_r_def - end if + do i = 1, ncells + if (lcbase(i,1) > 0) then + pres_lowest_cv_base(map_2d(1,i)) = p_rho_levels(i,1,lcbase(i,1)) + else + pres_lowest_cv_base(map_2d(1,i))= 0.0_r_def + end if + end do end if ! component A of upward mass flux if (.not. associated(massflux_up_cmpta, empty_real_data) ) then do k = 1, n_conv_levels - 1 - if ( (1.0_r_def - max_mf_fall) * massflux_up_half(map_w3(1) + k-1) < & - massflux_up_half(map_w3(1) + k) ) then - massflux_up_cmpta(map_w3(1) + k-1) = massflux_up_half(map_w3(1) + k-1) & - * (1.0_r_def - shallow_in_col(map_2d(1))) - else - massflux_up_cmpta(map_w3(1) + k-1) = 0.0_r_def - end if - end do + do i = 1, ncells + if ( (1.0_r_def - max_mf_fall) * massflux_up_half(map_w3(1,i) + k-1) < & + massflux_up_half(map_w3(1,i) + k) ) then + massflux_up_cmpta(map_w3(1,i) + k-1) = massflux_up_half(map_w3(1,i) + k-1) & + * (1.0_r_def - shallow_in_col(map_2d(1,i))) + else + massflux_up_cmpta(map_w3(1,i) + k-1) = 0.0_r_def + end if + end do ! i + end do ! k end if ! Convection theta increment without shallow for VAR if (.not. associated(dth_conv_noshal, empty_real_data) ) then do k = 0, nlayers - dth_conv_noshal(map_wth(1) + k) = dt_conv(map_wth(1) + k) / & - exner_in_wth(map_wth(1) + k) * & - (1.0_r_def - shallow_in_col(map_2d(1))) + do i = 1, ncells + dth_conv_noshal(map_wth(1,i) + k) = dt_conv(map_wth(1,i) + k) / & + exner_in_wth(map_wth(1,i) + k) * & + (1.0_r_def - shallow_in_col(map_2d(1,i))) + end do end do end if ! Convection mixing ratio increment without shallow for VAR if (.not. associated(dmv_conv_noshal, empty_real_data) ) then do k = 0, nlayers - dmv_conv_noshal(map_wth(1) + k) = dmv_conv(map_wth(1) + k) * & - (1.0_r_def - shallow_in_col(map_2d(1))) + do i = 1, ncells + dmv_conv_noshal(map_wth(1,i) + k) = dmv_conv(map_wth(1,i) + k) * & + (1.0_r_def - shallow_in_col(map_2d(1,i))) + end do end do end if ! provide some estimate of TKE in convective plumes, based on ! the mass flux and convective cloud area do k = 1, bl_levels - tke_bl(map_wth(1)+k) = MIN(max_tke,MAX(tke_bl(map_wth(1)+k), & - ( massflux_up(map_wth(1)+k) / ( g*rho_wet_tq(1,1,k)* & - MIN(0.5_r_um,MAX(0.05_r_um,cca_2d(map_2d(1)))) ) )**2)) - ! 0.5 and 0.05 are used here as plausible max and min - ! values of CCA to prevent numerical problems + do i = 1, ncells + tke_bl(map_wth(1,i)+k) = MIN(max_tke,MAX(tke_bl(map_wth(1,i)+k), & + ( massflux_up(map_wth(1,i)+k) / ( g*rho_wet_tq(i,1,k)* & + MIN(0.5_r_um,MAX(0.05_r_um,cca_2d(map_2d(1,i)))) ) )**2)) + ! 0.5 and 0.05 are used here as plausible max and min + ! values of CCA to prevent numerical problems + end do end do end if ! outer_iterations ! Copy tracers back to LFRic fields if ( outer == outer_iterations .AND. l_tracer ) then - do i = 1, ntra_fld - select case(ukca_tracer_names(i)) + do n = 1, ntra_fld + select case(ukca_tracer_names(n)) case(fldname_o3p) - o3p( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - o3p( map_wth(1) + 0 ) = o3p( map_wth(1) + 1 ) + do i = 1, ncells + o3p( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + o3p( map_wth(1,i) + 0 ) = o3p( map_wth(1,i) + 1 ) + end do case(fldname_o1d) - o1d( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - o1d( map_wth(1) + 0 ) = o1d( map_wth(1) + 1 ) + do i = 1, ncells + o1d( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + o1d( map_wth(1,i) + 0 ) = o1d( map_wth(1,i) + 1 ) + end do case(fldname_o3) - o3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - o3( map_wth(1) + 0 ) = o3( map_wth(1) + 1 ) + do i = 1, ncells + o3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + o3( map_wth(1,i) + 0 ) = o3( map_wth(1,i) + 1 ) + end do case(fldname_n) - n( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n( map_wth(1) + 0 ) = n( map_wth(1) + 1 ) + do i = 1, ncells + nit( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + nit( map_wth(1,i) + 0 ) = nit( map_wth(1,i) + 1 ) + end do case(fldname_no) - no( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - no( map_wth(1) + 0 ) = no( map_wth(1) + 1 ) + do i = 1, ncells + no( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + no( map_wth(1,i) + 0 ) = no( map_wth(1,i) + 1 ) + end do case(fldname_no3) - no3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - no3( map_wth(1) + 0 ) = no3( map_wth(1) + 1 ) + do i = 1, ncells + no3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + no3( map_wth(1,i) + 0 ) = no3( map_wth(1,i) + 1 ) + end do case(fldname_lumped_n) - lumped_n( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - lumped_n( map_wth(1) + 0 ) = lumped_n( map_wth(1) + 1 ) + do i = 1, ncells + lumped_n( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + lumped_n( map_wth(1,i) + 0 ) = lumped_n( map_wth(1,i) + 1 ) + end do case(fldname_n2o5) - n2o5( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n2o5( map_wth(1) + 0 ) = n2o5( map_wth(1) + 1 ) + do i = 1, ncells + n2o5( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n2o5( map_wth(1,i) + 0 ) = n2o5( map_wth(1,i) + 1 ) + end do case(fldname_ho2no2) - ho2no2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ho2no2( map_wth(1) + 0 ) = ho2no2( map_wth(1) + 1 ) + do i = 1, ncells + ho2no2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ho2no2( map_wth(1,i) + 0 ) = ho2no2( map_wth(1,i) + 1 ) + end do case(fldname_hono2) - hono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hono2( map_wth(1) + 0 ) = hono2( map_wth(1) + 1 ) + do i = 1, ncells + hono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hono2( map_wth(1,i) + 0 ) = hono2( map_wth(1,i) + 1 ) + end do case(fldname_h2o2) - h2o2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - h2o2( map_wth(1) + 0 ) = h2o2( map_wth(1) + 1 ) + do i = 1, ncells + h2o2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + h2o2( map_wth(1,i) + 0 ) = h2o2( map_wth(1,i) + 1 ) + end do case(fldname_ch4) - ch4( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ch4( map_wth(1) + 0 ) = ch4( map_wth(1) + 1 ) + do i = 1, ncells + ch4( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ch4( map_wth(1,i) + 0 ) = ch4( map_wth(1,i) + 1 ) + end do case(fldname_co) - co( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - co( map_wth(1) + 0 ) = co( map_wth(1) + 1 ) + do i = 1, ncells + co( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + co( map_wth(1,i) + 0 ) = co( map_wth(1,i) + 1 ) + end do case(fldname_hcho) - hcho( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hcho( map_wth(1) + 0 ) = hcho( map_wth(1) + 1 ) + do i = 1, ncells + hcho( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hcho( map_wth(1,i) + 0 ) = hcho( map_wth(1,i) + 1 ) + end do case(fldname_meoo) - meoo( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - meoo( map_wth(1) + 0 ) = meoo( map_wth(1) + 1 ) + do i = 1, ncells + meoo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + meoo( map_wth(1,i) + 0 ) = meoo( map_wth(1,i) + 1 ) + end do case(fldname_meooh) - meooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - meooh( map_wth(1) + 0 ) = meooh( map_wth(1) + 1 ) + do i = 1, ncells + meooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + meooh( map_wth(1,i) + 0 ) = meooh( map_wth(1,i) + 1 ) + end do case(fldname_h) - h( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - h( map_wth(1) + 0 ) = h( map_wth(1) + 1 ) + do i = 1, ncells + h( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + h( map_wth(1,i) + 0 ) = h( map_wth(1,i) + 1 ) + end do case(fldname_ch2o) + ! H2O tracer from chemistry ns not transported case(fldname_oh) - oh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - oh( map_wth(1) + 0 ) = oh( map_wth(1) + 1 ) + do i = 1, ncells + oh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + oh( map_wth(1,i) + 0 ) = oh( map_wth(1,i) + 1 ) + end do case(fldname_ho2) - ho2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ho2( map_wth(1) + 0 ) = ho2( map_wth(1) + 1 ) + do i = 1, ncells + ho2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ho2( map_wth(1,i) + 0 ) = ho2( map_wth(1,i) + 1 ) + end do case(fldname_cl) - cl( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cl( map_wth(1) + 0 ) = cl( map_wth(1) + 1 ) + do i = 1, ncells + cl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cl( map_wth(1,i) + 0 ) = cl( map_wth(1,i) + 1 ) + end do case(fldname_cl2o2) - cl2o2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cl2o2( map_wth(1) + 0 ) = cl2o2( map_wth(1) + 1 ) + do i = 1, ncells + cl2o2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cl2o2( map_wth(1,i) + 0 ) = cl2o2( map_wth(1,i) + 1 ) + end do case(fldname_clo) - clo( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - clo( map_wth(1) + 0 ) = clo( map_wth(1) + 1 ) + do i = 1, ncells + clo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + clo( map_wth(1,i) + 0 ) = clo( map_wth(1,i) + 1 ) + end do case(fldname_oclo) - oclo( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - oclo( map_wth(1) + 0 ) = oclo( map_wth(1) + 1 ) + do i = 1, ncells + oclo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + oclo( map_wth(1,i) + 0 ) = oclo( map_wth(1,i) + 1 ) + end do case(fldname_br) - br( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - br( map_wth(1) + 0 ) = br( map_wth(1) + 1 ) + do i = 1, ncells + br( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + br( map_wth(1,i) + 0 ) = br( map_wth(1,i) + 1 ) + end do case(fldname_lumped_br) - lumped_br( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - lumped_br( map_wth(1) + 0 ) = lumped_br( map_wth(1) + 1 ) + do i = 1, ncells + lumped_br( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + lumped_br( map_wth(1,i) + 0 ) = lumped_br( map_wth(1,i) + 1 ) + end do case(fldname_brcl) - brcl( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - brcl( map_wth(1) + 0 ) = brcl( map_wth(1) + 1 ) + do i = 1, ncells + brcl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + brcl( map_wth(1,i) + 0 ) = brcl( map_wth(1,i) + 1 ) + end do case(fldname_brono2) - brono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - brono2( map_wth(1) + 0 ) = brono2( map_wth(1) + 1 ) + do i = 1, ncells + brono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + brono2( map_wth(1,i) + 0 ) = brono2( map_wth(1,i) + 1 ) + end do case(fldname_n2o) - n2o( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n2o( map_wth(1) + 0 ) = n2o( map_wth(1) + 1 ) + do i = 1, ncells + n2o( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n2o( map_wth(1,i) + 0 ) = n2o( map_wth(1,i) + 1 ) + end do case(fldname_lumped_cl) - lumped_cl( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - lumped_cl( map_wth(1) + 0 ) = lumped_cl( map_wth(1) + 1 ) + do i = 1, ncells + lumped_cl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + lumped_cl( map_wth(1,i) + 0 ) = lumped_cl( map_wth(1,i) + 1 ) + end do case(fldname_hocl) - hocl( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hocl( map_wth(1) + 0 ) = hocl( map_wth(1) + 1 ) + do i = 1, ncells + hocl( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hocl( map_wth(1,i) + 0 ) = hocl( map_wth(1,i) + 1 ) + end do case(fldname_hbr) - hbr( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hbr( map_wth(1) + 0 ) = hbr( map_wth(1) + 1 ) + do i = 1, ncells + hbr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hbr( map_wth(1,i) + 0 ) = hbr( map_wth(1,i) + 1 ) + end do case(fldname_hobr) - hobr( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hobr( map_wth(1) + 0 ) = hobr( map_wth(1) + 1 ) + do i = 1, ncells + hobr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hobr( map_wth(1,i) + 0 ) = hobr( map_wth(1,i) + 1 ) + end do case(fldname_clono2) - clono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - clono2( map_wth(1) + 0 ) = clono2( map_wth(1) + 1 ) + do i = 1, ncells + clono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + clono2( map_wth(1,i) + 0 ) = clono2( map_wth(1,i) + 1 ) + end do case(fldname_cfcl3) - cfcl3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cfcl3( map_wth(1) + 0 ) = cfcl3( map_wth(1) + 1 ) + do i = 1, ncells + cfcl3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cfcl3( map_wth(1,i) + 0 ) = cfcl3( map_wth(1,i) + 1 ) + end do case(fldname_cf2cl2) - cf2cl2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cf2cl2( map_wth(1) + 0 ) = cf2cl2( map_wth(1) + 1 ) + do i = 1, ncells + cf2cl2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cf2cl2( map_wth(1,i) + 0 ) = cf2cl2( map_wth(1,i) + 1 ) + end do case(fldname_mebr) - mebr( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - mebr( map_wth(1) + 0 ) = mebr( map_wth(1) + 1 ) + do i = 1, ncells + mebr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + mebr( map_wth(1,i) + 0 ) = mebr( map_wth(1,i) + 1 ) + end do case(fldname_hono) - hono( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hono( map_wth(1) + 0 ) = hono( map_wth(1) + 1 ) + do i = 1, ncells + hono( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hono( map_wth(1,i) + 0 ) = hono( map_wth(1,i) + 1 ) + end do case(fldname_c2h6) - c2h6( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - c2h6( map_wth(1) + 0 ) = c2h6( map_wth(1) + 1 ) + do i = 1, ncells + c2h6( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + c2h6( map_wth(1,i) + 0 ) = c2h6( map_wth(1,i) + 1 ) + end do case(fldname_etoo) - etoo( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - etoo( map_wth(1) + 0 ) = etoo( map_wth(1) + 1 ) + do i = 1, ncells + etoo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + etoo( map_wth(1,i) + 0 ) = etoo( map_wth(1,i) + 1 ) + end do case(fldname_etooh) - etooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - etooh( map_wth(1) + 0 ) = etooh( map_wth(1) + 1 ) + do i = 1, ncells + etooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + etooh( map_wth(1,i) + 0 ) = etooh( map_wth(1,i) + 1 ) + end do case(fldname_mecho) - mecho( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - mecho( map_wth(1) + 0 ) = mecho( map_wth(1) + 1 ) + do i = 1, ncells + mecho( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + mecho( map_wth(1,i) + 0 ) = mecho( map_wth(1,i) + 1 ) + end do case(fldname_meco3) - meco3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - meco3( map_wth(1) + 0 ) = meco3( map_wth(1) + 1 ) + do i = 1, ncells + meco3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + meco3( map_wth(1,i) + 0 ) = meco3( map_wth(1,i) + 1 ) + end do case(fldname_pan) - pan( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - pan( map_wth(1) + 0 ) = pan( map_wth(1) + 1 ) + do i = 1, ncells + pan( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + pan( map_wth(1,i) + 0 ) = pan( map_wth(1,i) + 1 ) + end do case(fldname_c3h8) - c3h8( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - c3h8( map_wth(1) + 0 ) = c3h8( map_wth(1) + 1 ) + do i = 1, ncells + c3h8( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + c3h8( map_wth(1,i) + 0 ) = c3h8( map_wth(1,i) + 1 ) + end do case(fldname_n_proo) - n_proo( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_proo( map_wth(1) + 0 ) = n_proo( map_wth(1) + 1 ) + do i = 1, ncells + n_proo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_proo( map_wth(1,i) + 0 ) = n_proo( map_wth(1,i) + 1 ) + end do case(fldname_i_proo) - i_proo( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - i_proo( map_wth(1) + 0 ) = i_proo( map_wth(1) + 1 ) + do i = 1, ncells + i_proo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + i_proo( map_wth(1,i) + 0 ) = i_proo( map_wth(1,i) + 1 ) + end do case(fldname_n_prooh) - n_prooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_prooh( map_wth(1) + 0 ) = n_prooh( map_wth(1) + 1 ) + do i = 1, ncells + n_prooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_prooh( map_wth(1,i) + 0 ) = n_prooh( map_wth(1,i) + 1 ) + end do case(fldname_i_prooh) - i_prooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - i_prooh( map_wth(1) + 0 ) = i_prooh( map_wth(1) + 1 ) + do i = 1, ncells + i_prooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + i_prooh( map_wth(1,i) + 0 ) = i_prooh( map_wth(1,i) + 1 ) + end do case(fldname_etcho) - etcho( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - etcho( map_wth(1) + 0 ) = etcho( map_wth(1) + 1 ) + do i = 1, ncells + etcho( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + etcho( map_wth(1,i) + 0 ) = etcho( map_wth(1,i) + 1 ) + end do case(fldname_etco3) - etco3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - etco3( map_wth(1) + 0 ) = etco3( map_wth(1) + 1 ) + do i = 1, ncells + etco3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + etco3( map_wth(1,i) + 0 ) = etco3( map_wth(1,i) + 1 ) + end do case(fldname_me2co) - me2co( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - me2co( map_wth(1) + 0 ) = me2co( map_wth(1) + 1 ) + do i = 1, ncells + me2co( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + me2co( map_wth(1,i) + 0 ) = me2co( map_wth(1,i) + 1 ) + end do case(fldname_mecoch2oo) - mecoch2oo( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - mecoch2oo( map_wth(1) + 0 ) = mecoch2oo( map_wth(1) + 1 ) + do i = 1, ncells + mecoch2oo( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + mecoch2oo( map_wth(1,i) + 0 ) = mecoch2oo( map_wth(1,i) + 1 ) + end do case(fldname_mecoch2ooh) - mecoch2ooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - mecoch2ooh( map_wth(1) + 0 ) = mecoch2ooh( map_wth(1) + 1 ) + do i = 1, ncells + mecoch2ooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + mecoch2ooh( map_wth(1,i) + 0 ) = mecoch2ooh( map_wth(1,i) + 1 ) + end do case(fldname_ppan) - ppan( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ppan( map_wth(1) + 0 ) = ppan( map_wth(1) + 1 ) + do i = 1, ncells + ppan( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ppan( map_wth(1,i) + 0 ) = ppan( map_wth(1,i) + 1 ) + end do case(fldname_meono2) - meono2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - meono2( map_wth(1) + 0 ) = meono2( map_wth(1) + 1 ) + do i = 1, ncells + meono2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + meono2( map_wth(1,i) + 0 ) = meono2( map_wth(1,i) + 1 ) + end do case(fldname_c5h8) - c5h8( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - c5h8( map_wth(1) + 0 ) = c5h8( map_wth(1) + 1 ) + do i = 1, ncells + c5h8( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + c5h8( map_wth(1,i) + 0 ) = c5h8( map_wth(1,i) + 1 ) + end do case(fldname_iso2) - iso2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - iso2( map_wth(1) + 0 ) = iso2( map_wth(1) + 1 ) + do i = 1, ncells + iso2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + iso2( map_wth(1,i) + 0 ) = iso2( map_wth(1,i) + 1 ) + end do case(fldname_isooh) - isooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - isooh( map_wth(1) + 0 ) = isooh( map_wth(1) + 1 ) + do i = 1, ncells + isooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + isooh( map_wth(1,i) + 0 ) = isooh( map_wth(1,i) + 1 ) + end do case(fldname_ison) - ison( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ison( map_wth(1) + 0 ) = ison( map_wth(1) + 1 ) + do i = 1, ncells + ison( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ison( map_wth(1,i) + 0 ) = ison( map_wth(1,i) + 1 ) + end do case(fldname_macr) - macr( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - macr( map_wth(1) + 0 ) = macr( map_wth(1) + 1 ) + do i = 1, ncells + macr( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + macr( map_wth(1,i) + 0 ) = macr( map_wth(1,i) + 1 ) + end do case(fldname_macro2) - macro2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - macro2( map_wth(1) + 0 ) = macro2( map_wth(1) + 1 ) + do i = 1, ncells + macro2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + macro2( map_wth(1,i) + 0 ) = macro2( map_wth(1,i) + 1 ) + end do case(fldname_macrooh) - macrooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - macrooh( map_wth(1) + 0 ) = macrooh( map_wth(1) + 1 ) + do i = 1, ncells + macrooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + macrooh( map_wth(1,i) + 0 ) = macrooh( map_wth(1,i) + 1 ) + end do case(fldname_mpan) - mpan( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - mpan( map_wth(1) + 0 ) = mpan( map_wth(1) + 1 ) + do i = 1, ncells + mpan( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + mpan( map_wth(1,i) + 0 ) = mpan( map_wth(1,i) + 1 ) + end do case(fldname_hacet) - hacet( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hacet( map_wth(1) + 0 ) = hacet( map_wth(1) + 1 ) + do i = 1, ncells + hacet( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hacet( map_wth(1,i) + 0 ) = hacet( map_wth(1,i) + 1 ) + end do case(fldname_mgly) - mgly( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - mgly( map_wth(1) + 0 ) = mgly( map_wth(1) + 1 ) + do i = 1, ncells + mgly( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + mgly( map_wth(1,i) + 0 ) = mgly( map_wth(1,i) + 1 ) + end do case(fldname_nald) - nald( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - nald( map_wth(1) + 0 ) = nald( map_wth(1) + 1 ) + do i = 1, ncells + nald( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + nald( map_wth(1,i) + 0 ) = nald( map_wth(1,i) + 1 ) + end do case(fldname_hcooh) - hcooh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - hcooh( map_wth(1) + 0 ) = hcooh( map_wth(1) + 1 ) + do i = 1, ncells + hcooh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + hcooh( map_wth(1,i) + 0 ) = hcooh( map_wth(1,i) + 1 ) + end do case(fldname_meco3h) - meco3h( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - meco3h( map_wth(1) + 0 ) = meco3h( map_wth(1) + 1 ) + do i = 1, ncells + meco3h( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + meco3h( map_wth(1,i) + 0 ) = meco3h( map_wth(1,i) + 1 ) + end do case(fldname_meco2h) - meco2h( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - meco2h( map_wth(1) + 0 ) = meco2h( map_wth(1) + 1 ) + do i = 1, ncells + meco2h( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + meco2h( map_wth(1,i) + 0 ) = meco2h( map_wth(1,i) + 1 ) + end do case(fldname_h2) - h2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - h2( map_wth(1) + 0 ) = h2( map_wth(1) + 1 ) + do i = 1, ncells + h2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + h2( map_wth(1,i) + 0 ) = h2( map_wth(1,i) + 1 ) + end do case(fldname_meoh) - meoh( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - meoh( map_wth(1) + 0 ) = meoh( map_wth(1) + 1 ) + do i = 1, ncells + meoh( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + meoh( map_wth(1,i) + 0 ) = meoh( map_wth(1,i) + 1 ) + end do case(fldname_msa) - msa( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - msa( map_wth(1) + 0 ) = msa( map_wth(1) + 1 ) + do i = 1, ncells + msa( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + msa( map_wth(1,i) + 0 ) = msa( map_wth(1,i) + 1 ) + end do case(fldname_nh3) - nh3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - nh3( map_wth(1) + 0 ) = nh3( map_wth(1) + 1 ) + do i = 1, ncells + nh3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + nh3( map_wth(1,i) + 0 ) = nh3( map_wth(1,i) + 1 ) + end do case(fldname_cs2) - cs2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cs2( map_wth(1) + 0 ) = cs2( map_wth(1) + 1 ) + do i = 1, ncells + cs2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cs2( map_wth(1,i) + 0 ) = cs2( map_wth(1,i) + 1 ) + end do case(fldname_csul) - csul( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - csul( map_wth(1) + 0 ) = csul( map_wth(1) + 1 ) + do i = 1, ncells + csul( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + csul( map_wth(1,i) + 0 ) = csul( map_wth(1,i) + 1 ) + end do case(fldname_h2s) - h2s( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - h2s( map_wth(1) + 0 ) = h2s( map_wth(1) + 1 ) + do i = 1, ncells + h2s( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + h2s( map_wth(1,i) + 0 ) = h2s( map_wth(1,i) + 1 ) + end do case(fldname_so3) - so3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - so3( map_wth(1) + 0 ) = so3( map_wth(1) + 1 ) + do i = 1, ncells + so3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + so3( map_wth(1,i) + 0 ) = so3( map_wth(1,i) + 1 ) + end do case(fldname_passive_o3) - passive_o3( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - passive_o3( map_wth(1) + 0 ) = passive_o3( map_wth(1) + 1 ) + do i = 1, ncells + passive_o3( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + passive_o3( map_wth(1,i) + 0 ) = passive_o3( map_wth(1,i) + 1 ) + end do case(fldname_age_of_air) - age_of_air( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - age_of_air( map_wth(1) + 0 ) = age_of_air( map_wth(1) + 1 ) + do i = 1, ncells + age_of_air( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + age_of_air( map_wth(1,i) + 0 ) = age_of_air( map_wth(1,i) + 1 ) + end do case(fldname_dms) - dms( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - dms( map_wth(1) + 0 ) = dms( map_wth(1) + 1 ) + do i = 1, ncells + dms( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + dms( map_wth(1,i) + 0 ) = dms( map_wth(1,i) + 1 ) + end do case(fldname_so2) - so2( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - so2( map_wth(1) + 0 ) = so2( map_wth(1) + 1 ) + do i = 1, ncells + so2( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + so2( map_wth(1,i) + 0 ) = so2( map_wth(1,i) + 1 ) + end do case(fldname_h2so4) - h2so4( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - h2so4( map_wth(1) + 0 ) = h2so4( map_wth(1) + 1 ) + do i = 1, ncells + h2so4( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + h2so4( map_wth(1,i) + 0 ) = h2so4( map_wth(1,i) + 1 ) + end do case(fldname_dmso) - dmso( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - dmso( map_wth(1) + 0 ) = dmso( map_wth(1) + 1 ) + do i = 1, ncells + dmso( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + dmso( map_wth(1,i) + 0 ) = dmso( map_wth(1,i) + 1 ) + end do case(fldname_monoterpene) - monoterpene( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - monoterpene( map_wth(1) + 0 ) = monoterpene( map_wth(1) + 1 ) + do i = 1, ncells + monoterpene( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + monoterpene( map_wth(1,i) + 0 ) = monoterpene( map_wth(1,i) + 1 ) + end do case(fldname_secondary_organic) - secondary_organic( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - secondary_organic( map_wth(1) + 0 ) = & - secondary_organic( map_wth(1) + 1 ) + do i = 1, ncells + secondary_organic( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + secondary_organic( map_wth(1,i) + 0 ) = & + secondary_organic( map_wth(1,i) + 1 ) + end do case(fldname_n_nuc_sol) - n_nuc_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_nuc_sol( map_wth(1) + 0 ) = n_nuc_sol( map_wth(1) + 1 ) + do i = 1, ncells + n_nuc_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_nuc_sol( map_wth(1,i) + 0 ) = n_nuc_sol( map_wth(1,i) + 1 ) + end do case(fldname_nuc_sol_su) - nuc_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - nuc_sol_su( map_wth(1) + 0 ) = nuc_sol_su( map_wth(1) + 1 ) + do i = 1, ncells + nuc_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + nuc_sol_su( map_wth(1,i) + 0 ) = nuc_sol_su( map_wth(1,i) + 1 ) + end do case(fldname_nuc_sol_om) - nuc_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - nuc_sol_om( map_wth(1) + 0 ) = nuc_sol_om( map_wth(1) + 1 ) + do i = 1, ncells + nuc_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + nuc_sol_om( map_wth(1,i) + 0 ) = nuc_sol_om( map_wth(1,i) + 1 ) + end do case(fldname_n_ait_sol) - n_ait_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_ait_sol( map_wth(1) + 0 ) = n_ait_sol( map_wth(1) + 1 ) + do i = 1, ncells + n_ait_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_ait_sol( map_wth(1,i) + 0 ) = n_ait_sol( map_wth(1,i) + 1 ) + end do case(fldname_ait_sol_su) - ait_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ait_sol_su( map_wth(1) + 0 ) = ait_sol_su( map_wth(1) + 1 ) + do i = 1, ncells + ait_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ait_sol_su( map_wth(1,i) + 0 ) = ait_sol_su( map_wth(1,i) + 1 ) + end do case(fldname_ait_sol_bc) - ait_sol_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ait_sol_bc( map_wth(1) + 0 ) = ait_sol_bc( map_wth(1) + 1 ) + do i = 1, ncells + ait_sol_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ait_sol_bc( map_wth(1,i) + 0 ) = ait_sol_bc( map_wth(1,i) + 1 ) + end do case(fldname_ait_sol_om) - ait_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ait_sol_om( map_wth(1) + 0 ) = ait_sol_om( map_wth(1) + 1 ) + do i = 1, ncells + ait_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ait_sol_om( map_wth(1,i) + 0 ) = ait_sol_om( map_wth(1,i) + 1 ) + end do case(fldname_n_acc_sol) - n_acc_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_acc_sol( map_wth(1) + 0 ) = n_acc_sol( map_wth(1) + 1 ) + do i = 1, ncells + n_acc_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_acc_sol( map_wth(1,i) + 0 ) = n_acc_sol( map_wth(1,i) + 1 ) + end do case(fldname_acc_sol_su) - acc_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - acc_sol_su( map_wth(1) + 0 ) = acc_sol_su( map_wth(1) + 1 ) + do i = 1, ncells + acc_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + acc_sol_su( map_wth(1,i) + 0 ) = acc_sol_su( map_wth(1,i) + 1 ) + end do case(fldname_acc_sol_bc) - acc_sol_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - acc_sol_bc( map_wth(1) + 0 ) = acc_sol_bc( map_wth(1) + 1 ) + do i = 1, ncells + acc_sol_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + acc_sol_bc( map_wth(1,i) + 0 ) = acc_sol_bc( map_wth(1,i) + 1 ) + end do case(fldname_acc_sol_om) - acc_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - acc_sol_om( map_wth(1) + 0 ) = acc_sol_om( map_wth(1) + 1 ) + do i = 1, ncells + acc_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + acc_sol_om( map_wth(1,i) + 0 ) = acc_sol_om( map_wth(1,i) + 1 ) + end do case(fldname_acc_sol_ss) - acc_sol_ss( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - acc_sol_ss( map_wth(1) + 0 ) = acc_sol_ss( map_wth(1) + 1 ) + do i = 1, ncells + acc_sol_ss( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + acc_sol_ss( map_wth(1,i) + 0 ) = acc_sol_ss( map_wth(1,i) + 1 ) + end do case(fldname_acc_sol_du) - ! No field to update + ! No field to update (always zero) case(fldname_n_cor_sol) - n_cor_sol( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_cor_sol( map_wth(1) + 0 ) = n_cor_sol( map_wth(1) + 1 ) + do i = 1, ncells + n_cor_sol( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_cor_sol( map_wth(1,i) + 0 ) = n_cor_sol( map_wth(1,i) + 1 ) + end do case(fldname_cor_sol_su) - cor_sol_su( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cor_sol_su( map_wth(1) + 0 ) = cor_sol_su( map_wth(1) + 1 ) + do i = 1, ncells + cor_sol_su( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cor_sol_su( map_wth(1,i) + 0 ) = cor_sol_su( map_wth(1,i) + 1 ) + end do case(fldname_cor_sol_bc) - cor_sol_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cor_sol_bc( map_wth(1) + 0 ) = cor_sol_bc( map_wth(1) + 1 ) + do i = 1, ncells + cor_sol_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cor_sol_bc( map_wth(1,i) + 0 ) = cor_sol_bc( map_wth(1,i) + 1 ) + end do case(fldname_cor_sol_om) - cor_sol_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cor_sol_om( map_wth(1) + 0 ) = cor_sol_om( map_wth(1) + 1 ) + do i = 1, ncells + cor_sol_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cor_sol_om( map_wth(1,i) + 0 ) = cor_sol_om( map_wth(1,i) + 1 ) + end do case(fldname_cor_sol_ss) - cor_sol_ss( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cor_sol_ss( map_wth(1) + 0 ) = cor_sol_ss( map_wth(1) + 1 ) + do i = 1, ncells + cor_sol_ss( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cor_sol_ss( map_wth(1,i) + 0 ) = cor_sol_ss( map_wth(1,i) + 1 ) + end do case(fldname_cor_sol_du) - ! No field to update + ! No field to update (always zero) case(fldname_n_ait_ins) - n_ait_ins( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_ait_ins( map_wth(1) + 0 ) = n_ait_ins( map_wth(1) + 1 ) + do i = 1, ncells + n_ait_ins( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_ait_ins( map_wth(1,i) + 0 ) = n_ait_ins( map_wth(1,i) + 1 ) + end do case(fldname_ait_ins_bc) - ait_ins_bc( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ait_ins_bc( map_wth(1) + 0 ) = ait_ins_bc( map_wth(1) + 1 ) + do i = 1, ncells + ait_ins_bc( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ait_ins_bc( map_wth(1,i) + 0 ) = ait_ins_bc( map_wth(1,i) + 1 ) + end do case(fldname_ait_ins_om) - ait_ins_om( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - ait_ins_om( map_wth(1) + 0 ) = ait_ins_om( map_wth(1) + 1 ) + do i = 1, ncells + ait_ins_om( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + ait_ins_om( map_wth(1,i) + 0 ) = ait_ins_om( map_wth(1,i) + 1 ) + end do case(fldname_n_acc_ins) - n_acc_ins( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_acc_ins( map_wth(1) + 0 ) = n_acc_ins( map_wth(1) + 1 ) + do i = 1, ncells + n_acc_ins( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_acc_ins( map_wth(1,i) + 0 ) = n_acc_ins( map_wth(1,i) + 1 ) + end do case(fldname_acc_ins_du) - acc_ins_du( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - acc_ins_du( map_wth(1) + 0 ) = acc_ins_du( map_wth(1) + 1 ) + do i = 1, ncells + acc_ins_du( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + acc_ins_du( map_wth(1,i) + 0 ) = acc_ins_du( map_wth(1,i) + 1 ) + end do case(fldname_n_cor_ins) - n_cor_ins( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - n_cor_ins( map_wth(1) + 0 ) = n_cor_ins( map_wth(1) + 1 ) + do i = 1, ncells + n_cor_ins( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + n_cor_ins( map_wth(1,i) + 0 ) = n_cor_ins( map_wth(1,i) + 1 ) + end do case(fldname_cor_ins_du) - cor_ins_du( map_wth(1) + 1 : map_wth(1) + ntra_lev ) = & - real( tot_tracer( 1, 1, :, i ), r_def ) - cor_ins_du( map_wth(1) + 0 ) = cor_ins_du( map_wth(1) + 1 ) + do i = 1, ncells + cor_ins_du( map_wth(1,i) + 1 : map_wth(1,i) + ntra_lev ) = & + real( tot_tracer( i, 1, :, n ), r_def ) + cor_ins_du( map_wth(1,i) + 0 ) = cor_ins_du( map_wth(1,i) + 1 ) + end do end select end do end if ! outer == outer_iterations .AND. l_tracer diff --git a/interfaces/physics_schemes_interface/source/kernel/glomap_aerosol_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/glomap_aerosol_kernel_mod.F90 index 65a42e3a9..350a8ec8e 100644 --- a/interfaces/physics_schemes_interface/source/kernel/glomap_aerosol_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/glomap_aerosol_kernel_mod.F90 @@ -35,13 +35,12 @@ module glomap_aerosol_kernel_mod type, public, extends(kernel_type) :: glomap_aerosol_kernel_type private - type(arg_type) :: meta_args(66) = (/ & + type(arg_type) :: meta_args(65) = (/ & arg_type(GH_SCALAR, GH_LOGICAL, GH_READ), & ! rad_this_tstep arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! theta_in_wth arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! exner_in_wth arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! cf_bulk arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! cf_liquid - arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! rh_crit arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! m_v arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! m_cf arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! n_nuc_sol @@ -120,7 +119,6 @@ module glomap_aerosol_kernel_mod !! in potential temperature space !> @param[in] cf_bulk Bulk cloud fraction !> @param[in] cf_liquid Liquid cloud fraction -!> @param[in] rh_crit Critical rel humidity !> @param[in] m_v aka q !> @param[in] m_cf aka qcf !> @param[in] n_nuc_sol Climatology aerosol field @@ -195,7 +193,6 @@ subroutine glomap_aerosol_code( nlayers, & exner_in_wth, & cf_bulk, & cf_liquid, & - rh_crit, & m_v, & m_cf, & n_nuc_sol, & @@ -266,6 +263,8 @@ subroutine glomap_aerosol_code( nlayers, & ! UM modules !--------------------------------------- + use cloud_inputs_mod, only: rhcrit + use glomap_clim_interface_mod, only: glomap_clim_interface use planet_constants_mod, only: p_zero, kappa @@ -295,7 +294,6 @@ subroutine glomap_aerosol_code( nlayers, & real(kind=r_def), intent(in), dimension(undf_wth) :: exner_in_wth real(kind=r_def), intent(in), dimension(undf_wth) :: cf_bulk real(kind=r_def), intent(in), dimension(undf_wth) :: cf_liquid - real(kind=r_def), intent(in), dimension(undf_wth) :: rh_crit real(kind=r_def), intent(in), dimension(undf_wth) :: m_v real(kind=r_def), intent(in), dimension(undf_wth) :: m_cf real(kind=r_def), intent(in), dimension(undf_wth) :: n_nuc_sol @@ -487,7 +485,7 @@ subroutine glomap_aerosol_code( nlayers, & qcf_um(k) = m_cf(map_wth(1) + k) cloud_blk_frac_um(k) = cf_bulk(map_wth(1) + k) cloud_liq_frac_um(k) = cf_liquid(map_wth(1) + k) - rh_crit_um(k) = rh_crit(map_wth(1) + k) + rh_crit_um(k) = rhcrit(k) end do !----------------------------------------------------------------------- diff --git a/interfaces/physics_schemes_interface/source/kernel/radaer_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/radaer_kernel_mod.F90 index 1a25974fa..c56207387 100644 --- a/interfaces/physics_schemes_interface/source/kernel/radaer_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/radaer_kernel_mod.F90 @@ -1139,7 +1139,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aod_ukca_ait_sol, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aod_ukca_ait_sol( map_aod_wavel(i) + k ) = aod_ukca_this_mode_um(i,k) + aod_ukca_ait_sol( map_aod_wavel(i) + k - 1 ) = & + aod_ukca_this_mode_um(i,k) end do end do end if @@ -1147,7 +1148,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aaod_ukca_ait_sol, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aaod_ukca_ait_sol( map_aod_wavel(i)+k ) = aaod_ukca_this_mode_um(i,k) + aaod_ukca_ait_sol( map_aod_wavel(i) + k - 1 ) = & + aaod_ukca_this_mode_um(i,k) end do end do end if @@ -1224,7 +1226,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aod_ukca_acc_sol, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aod_ukca_acc_sol( map_aod_wavel(i) + k ) = aod_ukca_this_mode_um(i,k) + aod_ukca_acc_sol( map_aod_wavel(i) + k - 1 ) = & + aod_ukca_this_mode_um(i,k) end do end do end if @@ -1232,7 +1235,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aaod_ukca_acc_sol, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aaod_ukca_acc_sol( map_aod_wavel(i)+k ) = aaod_ukca_this_mode_um(i,k) + aaod_ukca_acc_sol( map_aod_wavel(i) + k - 1 ) = & + aaod_ukca_this_mode_um(i,k) end do end do end if @@ -1309,7 +1313,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aod_ukca_cor_sol, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aod_ukca_cor_sol( map_aod_wavel(i) + k ) = aod_ukca_this_mode_um(i,k) + aod_ukca_cor_sol( map_aod_wavel(i) + k - 1 ) = & + aod_ukca_this_mode_um(i,k) end do end do end if @@ -1317,7 +1322,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aaod_ukca_cor_sol, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aaod_ukca_cor_sol( map_aod_wavel(i)+k ) = aaod_ukca_this_mode_um(i,k) + aaod_ukca_cor_sol( map_aod_wavel(i) + k - 1 ) = & + aaod_ukca_this_mode_um(i,k) end do end do end if @@ -1394,7 +1400,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aod_ukca_ait_ins, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aod_ukca_ait_ins( map_aod_wavel(i) + k ) = aod_ukca_this_mode_um(i,k) + aod_ukca_ait_ins( map_aod_wavel(i) + k - 1 ) = & + aod_ukca_this_mode_um(i,k) end do end do end if @@ -1402,7 +1409,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aaod_ukca_ait_ins, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aaod_ukca_ait_ins( map_aod_wavel(i)+k ) = aaod_ukca_this_mode_um(i,k) + aaod_ukca_ait_ins( map_aod_wavel(i) + k - 1 ) = & + aaod_ukca_this_mode_um(i,k) end do end do end if @@ -1479,7 +1487,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aod_ukca_acc_ins, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aod_ukca_acc_ins( map_aod_wavel(i) + k ) = aod_ukca_this_mode_um(i,k) + aod_ukca_acc_ins( map_aod_wavel(i) + k - 1 ) = & + aod_ukca_this_mode_um(i,k) end do end do end if @@ -1487,7 +1496,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aaod_ukca_acc_ins, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aaod_ukca_acc_ins( map_aod_wavel(i)+k ) = aaod_ukca_this_mode_um(i,k) + aaod_ukca_acc_ins( map_aod_wavel(i) + k - 1 ) = & + aaod_ukca_this_mode_um(i,k) end do end do end if @@ -1564,7 +1574,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aod_ukca_cor_ins, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aod_ukca_cor_ins( map_aod_wavel(i) + k ) = aod_ukca_this_mode_um(i,k) + aod_ukca_cor_ins( map_aod_wavel(i) + k - 1 ) = & + aod_ukca_this_mode_um(i,k) end do end do end if @@ -1572,7 +1583,8 @@ subroutine radaer_code( nlayers, & if ( .not. associated( aaod_ukca_cor_ins, empty_real_data ) ) then do k = 1, npd_ukca_aod_wavel do i = 1, row_length - aaod_ukca_cor_ins( map_aod_wavel(i)+k ) = aaod_ukca_this_mode_um(i,k) + aaod_ukca_cor_ins( map_aod_wavel(i) + k - 1 ) = & + aaod_ukca_this_mode_um(i,k) end do end do end if diff --git a/interfaces/physics_schemes_interface/source/kernel/stph/skeb_biharm_diss_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/stph/skeb_biharm_diss_kernel_mod.F90 index c10d72912..7bd349755 100644 --- a/interfaces/physics_schemes_interface/source/kernel/stph/skeb_biharm_diss_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/stph/skeb_biharm_diss_kernel_mod.F90 @@ -9,18 +9,18 @@ module skeb_biharm_diss_kernel_mod use argument_mod, only: arg_type, GH_FIELD, & GH_REAL, GH_WRITE, GH_READ, & CELL_COLUMN, GH_INTEGER, & - GH_SCALAR, STENCIL, CROSS + GH_SCALAR, STENCIL, CROSS, & + GH_LOGICAL use fs_continuity_mod, only: W3, Wtheta, W1, W2 - use constants_mod, only: r_def, i_def + use constants_mod, only: r_def, i_def, l_def use kernel_mod, only: kernel_type - use empty_data_mod, only: empty_real_data implicit none !> Kernel metadata for Psyclone type, public, extends(kernel_type) :: skeb_biharm_diss_kernel_type private - type(arg_type) :: meta_args(9) = (/ & + type(arg_type) :: meta_args(11) = (/ & arg_type(GH_FIELD, GH_REAL, GH_WRITE, W3), & ! ndisp arg_type(GH_FIELD, GH_REAL, GH_READ, W1), & ! vorticity arg_type(GH_FIELD, GH_REAL, GH_READ, W3, STENCIL(CROSS)), & ! divergence @@ -29,7 +29,9 @@ module skeb_biharm_diss_kernel_mod arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! skeb_level_top arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! dt arg_type(GH_FIELD, GH_REAL, GH_WRITE, W3), & ! norm_xi - arg_type(GH_FIELD, GH_REAL, GH_WRITE, W3) & ! norm_div + arg_type(GH_FIELD, GH_REAL, GH_WRITE, W3), & ! norm_div + arg_type(GH_SCALAR, GH_LOGICAL, GH_READ), & ! norm_xi_flag + arg_type(GH_SCALAR, GH_LOGICAL, GH_READ) & ! norm_div_flag /) integer :: operates_on = CELL_COLUMN @@ -60,6 +62,8 @@ module skeb_biharm_diss_kernel_mod !> @param[in] ndf_w2 Number of DOFs per cell for w2 space !> @param[in] undf_w2 Number of unique DOFs for w2 space !> @param[in] map_w2 dofmap for the cell at the base of the column for w2 space + !> @param[in] norm_xi_flag Control whether norm_xi calculation is needed + !> @param[in] norm_div_flag Control whether norm_div calculation is needed subroutine skeb_biharm_diss_code(nlayers, & ndisp, & @@ -73,6 +77,8 @@ subroutine skeb_biharm_diss_code(nlayers, & dt, & norm_xi, & norm_div, & + norm_xi_flag, & + norm_div_flag, & ndf_w3, & undf_w3, & map_w3, & @@ -94,6 +100,8 @@ subroutine skeb_biharm_diss_code(nlayers, & integer(kind=i_def), intent(in), dimension(ndf_w2) :: map_w2 integer(kind=i_def), intent(in), dimension(ndf_w3,map_w3_sten_size) :: map_w3_sten integer(kind=i_def), intent(in), dimension(ndf_w1) :: map_w1 + logical(kind=l_def), intent(in) :: norm_xi_flag + logical(kind=l_def), intent(in) :: norm_div_flag ! Fields real(kind=r_def), intent(in), dimension(undf_w1) :: vorticity @@ -156,10 +164,10 @@ subroutine skeb_biharm_diss_code(nlayers, & ndisp(map_w3(1)+k-1) = (biharmonic_x_div + biharmonic_y_div + & biharmonic_x_xi + biharmonic_y_xi) * amp_K - if (.not. associated(norm_xi, empty_real_data)) then + if (norm_xi_flag) then norm_xi(map_w3(1)+k-1) = biharmonic_x_xi + biharmonic_y_xi end if - if (.not. associated(norm_div, empty_real_data)) then + if (norm_div_flag) then norm_div(map_w3(1)+k-1) = biharmonic_x_div + biharmonic_y_div end if diff --git a/interfaces/physics_schemes_interface/source/kernel/stph/spt_convection_cfl_limit_cap_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/stph/spt_convection_cfl_limit_cap_kernel_mod.F90 index 71f156fec..7a4ca2a7a 100644 --- a/interfaces/physics_schemes_interface/source/kernel/stph/spt_convection_cfl_limit_cap_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/stph/spt_convection_cfl_limit_cap_kernel_mod.F90 @@ -8,9 +8,11 @@ module spt_convection_cfl_limit_cap_kernel_mod use argument_mod, only: arg_type, GH_FIELD, & GH_WRITE, GH_REAL, & + GH_SCALAR, GH_INTEGER, & GH_READ, CELL_COLUMN use fs_continuity_mod, only: Wtheta - use constants_mod, only: r_def, i_def, l_def + use constants_mod, only: r_def, i_def, l_def, & + r_second use kernel_mod, only: kernel_type implicit none @@ -24,11 +26,14 @@ module spt_convection_cfl_limit_cap_kernel_mod !> type, public, extends(kernel_type) :: spt_convection_cfl_limit_cap_kernel_type private - type(arg_type) :: meta_args(4) = (/ & + type(arg_type) :: meta_args(7) = (/ & arg_type(GH_FIELD, GH_REAL, GH_WRITE, WTHETA), & ! dX_conv_cfl arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! massflux_up arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! fp_spt - arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA) & ! pressure + arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & ! pressure + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! spt_level_bottom + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! spt_level_top + arg_type(GH_SCALAR, GH_REAL, GH_READ) & ! dt /) integer :: operates_on = CELL_COLUMN contains @@ -52,20 +57,20 @@ module spt_convection_cfl_limit_cap_kernel_mod !> @param[in] ndf_wth Number of degrees of freedom per cell for wtheta !> @param[in] undf_wth Number of total degrees of freedom for wtheta !> @param[in] map_wth Dofmap for the cell at the base of the column - subroutine spt_convection_cfl_limit_cap_code(nlayers, & - dX_conv_cfl, & - massflux_up, & - fp_spt, & - pressure, & - ndf_wth, & - undf_wth, & - map_wth & - ) - - use stochastic_physics_config_mod, only: spt_level_bottom, & - spt_level_top - - use timestepping_config_mod, only: dt + !> @param[in] spt_level_bottom Bottom level of the stochastic scheme + !> @param[in] spt_level_top Top level of the stochastic scheme + !> @param[in] dt Timestep from timestepping_config_mod + subroutine spt_convection_cfl_limit_cap_code(nlayers, & + dX_conv_cfl, & + massflux_up, & + fp_spt, & + pressure, & + spt_level_bottom, & + spt_level_top, & + dt, & + ndf_wth, & + undf_wth, & + map_wth) implicit none @@ -74,6 +79,9 @@ subroutine spt_convection_cfl_limit_cap_code(nlayers, & integer(kind=i_def), intent(in) :: ndf_wth integer(kind=i_def), intent(in) :: undf_wth integer(kind=i_def), intent(in), dimension(ndf_wth) :: map_wth + integer(kind=i_def), intent(in) :: spt_level_bottom + integer(kind=i_def), intent(in) :: spt_level_top + real(kind=r_second), intent(in) :: dt ! Fields perturbations + tendencies real(kind=r_def), intent(inout), dimension(undf_wth) :: dX_conv_cfl diff --git a/interfaces/physics_schemes_interface/source/kernel/stph/spt_levels_cap_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/stph/spt_levels_cap_kernel_mod.F90 index ac3b44fbc..a359f5009 100644 --- a/interfaces/physics_schemes_interface/source/kernel/stph/spt_levels_cap_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/stph/spt_levels_cap_kernel_mod.F90 @@ -8,7 +8,8 @@ module spt_levels_cap_kernel_mod use argument_mod, only: arg_type, GH_FIELD, & GH_WRITE, GH_REAL, & - CELL_COLUMN + GH_SCALAR, GH_INTEGER, & + GH_READ, CELL_COLUMN use fs_continuity_mod, only: Wtheta @@ -26,8 +27,12 @@ module spt_levels_cap_kernel_mod !> type, public, extends(kernel_type) :: spt_levels_cap_kernel_type private - type(arg_type) :: meta_args(1) = (/ & - arg_type(GH_FIELD, GH_REAL, GH_WRITE, WTHETA) & !dX + type(arg_type) :: meta_args(5) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_WRITE, WTHETA), & !dX + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! spt_level_bottom + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! spt_level_top + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! spt_level_begin_tapering_bottom + arg_type(GH_SCALAR, GH_INTEGER, GH_READ) & ! spt_level_begin_tapering_top /) integer :: operates_on = CELL_COLUMN contains @@ -49,19 +54,22 @@ module spt_levels_cap_kernel_mod !> @param[in] ndf_wth Number of degrees of freedom per cell for wtheta !> @param[in] undf_wth Number of total degrees of freedom for wtheta !> @param[in] map_wth Dofmap for the cell at the base of the column - - subroutine spt_levels_cap_code(nlayers, & - dX, & - ndf_wth, & - undf_wth, & - map_wth & + !> @param[in] spt_level_bottom Bottom level of the stochastic scheme + !> @param[in] spt_level_top Top level of the stochastic scheme + !> @param[in] spt_level_begin_tapering_bottom spt_level_begin_tapering_bottom in stochastic_physics_config_mod + !> @param[in] spt_level_begin_tapering_top spt_level_begin_tapering_top in stochastic_physics_config_mod + + subroutine spt_levels_cap_code(nlayers, & + dX, & + spt_level_bottom, & + spt_level_top, & + spt_level_begin_tapering_bottom, & + spt_level_begin_tapering_top, & + ndf_wth, & + undf_wth, & + map_wth & ) - use stochastic_physics_config_mod, only: spt_level_bottom, & - spt_level_top, & - spt_level_begin_tapering_bottom, & - spt_level_begin_tapering_top - implicit none !Arguments @@ -69,6 +77,10 @@ subroutine spt_levels_cap_code(nlayers, & integer(kind=i_def), intent(in) :: ndf_wth integer(kind=i_def), intent(in) :: undf_wth integer(kind=i_def), intent(in), dimension(ndf_wth) :: map_wth + integer(kind=i_def), intent(in) :: spt_level_bottom + integer(kind=i_def), intent(in) :: spt_level_top + integer(kind=i_def), intent(in) :: spt_level_begin_tapering_bottom + integer(kind=i_def), intent(in) :: spt_level_begin_tapering_top ! field with perturbation real(kind=r_def), intent(inout), dimension(undf_wth) :: dX diff --git a/interfaces/physics_schemes_interface/source/kernel/stph/spt_moisture_conservation_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/stph/spt_moisture_conservation_kernel_mod.F90 index d4bf26dd9..001c90bdc 100644 --- a/interfaces/physics_schemes_interface/source/kernel/stph/spt_moisture_conservation_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/stph/spt_moisture_conservation_kernel_mod.F90 @@ -8,6 +8,7 @@ module spt_moisture_conservation_kernel_mod use argument_mod, only: arg_type, GH_FIELD, & GH_WRITE, GH_REAL, & + GH_SCALAR, GH_INTEGER, & GH_READ, CELL_COLUMN use fs_continuity_mod, only: Wtheta use constants_mod, only: r_def, i_def @@ -24,11 +25,13 @@ module spt_moisture_conservation_kernel_mod !> type, public, extends(kernel_type) :: spt_moisture_conservation_kernel_type private - type(arg_type) :: meta_args(4) = (/ & + type(arg_type) :: meta_args(6) = (/ & arg_type(GH_FIELD, GH_REAL, GH_WRITE, WTHETA), & !dmv arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & !mv arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & !dz_wth - arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA) & !rho_wth + arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & !rho_wth + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & !spt_level_bottom + arg_type(GH_SCALAR, GH_INTEGER, GH_READ) & !spt_level_top /) integer :: operates_on = CELL_COLUMN @@ -53,19 +56,21 @@ module spt_moisture_conservation_kernel_mod !> @param[in] ndf_wth Number of DOFs per cell for potential temperature space !> @param[in] undf_wth Number of unique DOFs for potential temperature space !> @param[in] map_wth dofmap for the cell at the base of the column for potential temperature space - - subroutine spt_moisture_conservation_code(nlayers, & - dmv, & - mv, & - rho_wth, & - dz_wth, & - ndf_wth, & - undf_wth, & - map_wth & + !> @param[in] spt_level_bottom Bottom level of the stochastic scheme + !> @param[in] spt_level_top Top level of the stochastic scheme + + subroutine spt_moisture_conservation_code(nlayers, & + dmv, & + mv, & + rho_wth, & + dz_wth, & + spt_level_bottom, & + spt_level_top, & + ndf_wth, & + undf_wth, & + map_wth & ) - use stochastic_physics_config_mod, only: spt_level_bottom, spt_level_top - implicit none !Arguments @@ -73,6 +78,8 @@ subroutine spt_moisture_conservation_code(nlayers, & integer(kind=i_def), intent(in) :: ndf_wth integer(kind=i_def), intent(in) :: undf_wth integer(kind=i_def), intent(in), dimension(ndf_wth) :: map_wth + integer(kind=i_def), intent(in) :: spt_level_bottom + integer(kind=i_def), intent(in) :: spt_level_top ! Fields real(kind=r_def), intent(inout), dimension(undf_wth) :: dmv diff --git a/interfaces/physics_schemes_interface/source/kernel/stph/spt_orog_cap_kernel_mod.F90 b/interfaces/physics_schemes_interface/source/kernel/stph/spt_orog_cap_kernel_mod.F90 index 3e51f5e18..6b15c66c5 100644 --- a/interfaces/physics_schemes_interface/source/kernel/stph/spt_orog_cap_kernel_mod.F90 +++ b/interfaces/physics_schemes_interface/source/kernel/stph/spt_orog_cap_kernel_mod.F90 @@ -8,6 +8,7 @@ module spt_orog_cap_kernel_mod use argument_mod, only: arg_type, GH_FIELD, & GH_WRITE, GH_REAL, & + GH_SCALAR, GH_INTEGER, & GH_READ, & ANY_DISCONTINUOUS_SPACE_1, & CELL_COLUMN @@ -27,10 +28,14 @@ module spt_orog_cap_kernel_mod !> type, public, extends(kernel_type) :: spt_orog_cap_kernel_type private - type(arg_type) :: meta_args(3) = (/ & + type(arg_type) :: meta_args(7) = (/ & arg_type(GH_FIELD, GH_REAL, GH_WRITE, WTHETA), & !dX arg_type(GH_FIELD, GH_REAL, GH_READ, WTHETA), & !fp_spt - arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1) & !sd_orog + arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1),& !sd_orog + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! spt_level_bottom + arg_type(GH_SCALAR, GH_INTEGER, GH_READ), & ! spt_level_top + arg_type(GH_SCALAR, GH_REAL, GH_READ), & ! spt_orog_forcing_pattern_thresh + arg_type(GH_SCALAR, GH_REAL, GH_READ) & ! spt_stddev_orog_thres /) integer :: operates_on = CELL_COLUMN @@ -58,24 +63,27 @@ module spt_orog_cap_kernel_mod !> @param[in] ndf_2d Number of degrees of freedom per cell for density space !> @param[in] undf_2d Number of unique degrees of freedom for density space !> @param[in] map_2d Dofmap for the cell at the base of the column for density space - - subroutine spt_orog_cap_code(nlayers, & - dX, & - fp_spt, & - sd_orog, & - ndf_wth, & - undf_wth, & - map_wth, & - ndf_2d, & - undf_2d, & - map_2d & + !> @param[in] spt_level_bottom Bottom level of the stochastic scheme + !> @param[in] spt_level_top Top level of the stochastic scheme + !> @param[in] spt_orog_forcing_pattern_thresh spt_orog_forcing_pattern_thresh in stochastic_physics_config_mod + !> @param[in] spt_stddev_orog_thres spt_stddev_orog_thres in stochastic_physics_config_mod + + subroutine spt_orog_cap_code(nlayers, & + dX, & + fp_spt, & + sd_orog, & + spt_level_bottom, & + spt_level_top, & + spt_orog_forcing_pattern_thresh, & + spt_stddev_orog_thres, & + ndf_wth, & + undf_wth, & + map_wth, & + ndf_2d, & + undf_2d, & + map_2d & ) - use stochastic_physics_config_mod, only: spt_level_bottom, & - spt_level_top, & - spt_orog_forcing_pattern_thresh, & - spt_stddev_orog_thres - implicit none !Arguments @@ -84,6 +92,10 @@ subroutine spt_orog_cap_code(nlayers, & integer(kind=i_def), intent(in) :: undf_wth, undf_2d integer(kind=i_def), intent(in), dimension(ndf_wth) :: map_wth integer(kind=i_def), intent(in), dimension(ndf_2d) :: map_2d + integer(kind=i_def), intent(in) :: spt_level_bottom + integer(kind=i_def), intent(in) :: spt_level_top + real(kind=r_def), intent(in) :: spt_orog_forcing_pattern_thresh + real(kind=r_def), intent(in) :: spt_stddev_orog_thres ! Fields perturbations + tendencies real(kind=r_def), intent(inout), dimension(undf_wth) :: dX diff --git a/interfaces/physics_schemes_interface/source/legacy/top_level/tuning_segments_mod.F90 b/interfaces/physics_schemes_interface/source/legacy/top_level/tuning_segments_mod.F90 index 2b0213962..3a5f8d7dd 100644 --- a/interfaces/physics_schemes_interface/source/legacy/top_level/tuning_segments_mod.F90 +++ b/interfaces/physics_schemes_interface/source/legacy/top_level/tuning_segments_mod.F90 @@ -46,6 +46,8 @@ module tuning_segments_mod integer :: ussp_seg_size = imdi ! Segment size for USSP gravity wave drag integer :: precip_segment_size = imdi +integer :: conv_gr_segment_size = imdi ! Segment size for GR convection scheme + integer :: a_convect_segments = imdi ! No of batches used in convection ! Original default 1 diff --git a/interfaces/physics_schemes_interface/source/legacy/ukca_interface/ukca_volcanic_so2.F90 b/interfaces/physics_schemes_interface/source/legacy/ukca_interface/ukca_volcanic_so2.F90 index 05f319418..da5d22651 100644 --- a/interfaces/physics_schemes_interface/source/legacy/ukca_interface/ukca_volcanic_so2.F90 +++ b/interfaces/physics_schemes_interface/source/legacy/ukca_interface/ukca_volcanic_so2.F90 @@ -150,6 +150,19 @@ subroutine ukca_volcanic_so2 & if (lhook) call dr_hook(ModuleName//':'//RoutineName,zhook_in,zhook_handle) +! Functionality is not currently implemented in LFRic. +errcode = 1 +cmessage = 'Volcanic SO2 emissions not yet implemented.' // & + 'Logical l_ukca_so2ems_expvolc should be set to .false.' +call ereport(RoutineName, errcode, cmessage) + +! Allocate true_latitude, true_longitude arrays and initialise temporarily. +! These should be subsequently populated from LFRic w3 fields. +if ( .not. allocated(true_latitude)) allocate(true_latitude(row_length,rows)) +if ( .not. allocated(true_longitude)) allocate(true_longitude(row_length,rows)) +true_latitude(:,:) = 0.0 +true_longitude(:,:) = 0.0 + ! On first call, determine locations on the UM grid where volcanos are located. ! The method assumes that the grid is a regular latitude-longitude grid with ! latitude constant on each row and equally-spaced between rows and @@ -334,6 +347,7 @@ subroutine ukca_volcanic_so2 & l2 = l2 - 1 end do if (l2 < l1) l1 = l2 + allocate(weight_volc_vertdist(l2-l1+1)) ! express emission as increase in average increase in mass mixing ratio weight_volc_vertdist = (abs(r_theta_levels(i,j,l1+1:l2+1) - & r_theta_levels(i,j,l1-1:l2-1))/2) * & @@ -343,10 +357,14 @@ subroutine ukca_volcanic_so2 & so2_mmr(i,j,l1:l2) = so2_mmr(i,j,l1:l2) + emission(k) * & (weight_volc_vertdist/sum(weight_volc_vertdist)) / & mass(i,j,l1:l2) + deallocate(weight_volc_vertdist) end if end if end do +if (allocated(true_latitude)) deallocate(true_latitude) +if (allocated(true_longitude)) deallocate(true_longitude) + if (lhook) call dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) return end subroutine ukca_volcanic_so2 diff --git a/interfaces/physics_schemes_interface/source/psy/psykal_lite_phys_mod.F90 b/interfaces/physics_schemes_interface/source/psy/psykal_lite_phys_mod.F90 index 71e723b3a..a064523c8 100644 --- a/interfaces/physics_schemes_interface/source/psy/psykal_lite_phys_mod.F90 +++ b/interfaces/physics_schemes_interface/source/psy/psykal_lite_phys_mod.F90 @@ -338,7 +338,7 @@ SUBROUTINE invoke_jules_exp_kernel_type(ncells, ncells_halo, theta, exner_in_wth &soil_moist_avail, snow_unload_rate, albedo_obs_scaling, soil_clay, soil_sand, dust_mrel, dust_flux, day_of_year, second_of_day, & flux_e, flux_h, urbwrr, urbhwr, urbhgt, urbztm, urbdisp, & &rhostar, recip_l_mo_sea, & -&h_blend_orog, t1_sd_2d, q1_sd_2d, gross_prim_prod, z0h_eff, ocn_cpl_point, stencil_depth) +&t1_sd_2d, q1_sd_2d, gross_prim_prod, z0h_eff, ocn_cpl_point, stencil_depth) USE jules_exp_kernel_mod, ONLY: jules_exp_code USE mesh_mod, ONLY: mesh_type USE stencil_dofmap_mod, ONLY: STENCIL_REGION @@ -358,7 +358,7 @@ SUBROUTINE invoke_jules_exp_kernel_type(ncells, ncells_halo, theta, exner_in_wth &chr1p5m_tile, resfs_tile, gc_tile, canhc_tile, tile_water_extract, z0m_eff, ustar, soil_moist_avail, snow_unload_rate, & &albedo_obs_scaling, soil_clay, soil_sand, dust_mrel, dust_flux, & urbwrr, urbhwr, urbhgt, urbztm, urbdisp, & -rhostar, recip_l_mo_sea, h_blend_orog, t1_sd_2d, q1_sd_2d, & +rhostar, recip_l_mo_sea, t1_sd_2d, q1_sd_2d, & &gross_prim_prod, z0h_eff TYPE(integer_field_type), intent(in) :: n_snow_layers, blend_height_tq, ocn_cpl_point INTEGER(KIND=i_def), intent(in) :: stencil_depth, ncells, ncells_halo, day_of_year, second_of_day @@ -385,7 +385,7 @@ SUBROUTINE invoke_jules_exp_kernel_type(ncells, ncells_halo, theta, exner_in_wth &tile_water_extract_proxy, z0m_eff_proxy, ustar_proxy, soil_moist_avail_proxy, snow_unload_rate_proxy, albedo_obs_scaling_proxy, & &soil_clay_proxy, soil_sand_proxy, dust_mrel_proxy, dust_flux_proxy, & urbwrr_proxy, urbhwr_proxy, urbhgt_proxy, urbztm_proxy, urbdisp_proxy, & -rhostar_proxy, recip_l_mo_sea_proxy, h_blend_orog_proxy, & +rhostar_proxy, recip_l_mo_sea_proxy, & &t1_sd_2d_proxy, q1_sd_2d_proxy, gross_prim_prod_proxy, z0h_eff_proxy INTEGER(KIND=i_def), pointer :: map_adspc10_dust_mrel(:,:) => null(), map_adspc1_zh(:,:) => null(), & &map_adspc2_tile_fraction(:,:) => null(), map_adspc3_leaf_area_index(:,:) => null(), & @@ -515,7 +515,6 @@ SUBROUTINE invoke_jules_exp_kernel_type(ncells, ncells_halo, theta, exner_in_wth urbdisp_proxy = urbdisp%get_proxy() rhostar_proxy = rhostar%get_proxy() recip_l_mo_sea_proxy = recip_l_mo_sea%get_proxy() - h_blend_orog_proxy = h_blend_orog%get_proxy() t1_sd_2d_proxy = t1_sd_2d%get_proxy() q1_sd_2d_proxy = q1_sd_2d%get_proxy() gross_prim_prod_proxy = gross_prim_prod%get_proxy() @@ -673,7 +672,7 @@ SUBROUTINE invoke_jules_exp_kernel_type(ncells, ncells_halo, theta, exner_in_wth urbwrr_proxy%data, urbhwr_proxy%data, urbhgt_proxy%data, urbztm_proxy%data, & urbdisp_proxy%data, & rhostar_proxy%data, recip_l_mo_sea_proxy%data, & -&h_blend_orog_proxy%data, t1_sd_2d_proxy%data, q1_sd_2d_proxy%data, gross_prim_prod_proxy%data, & +&t1_sd_2d_proxy%data, q1_sd_2d_proxy%data, gross_prim_prod_proxy%data, & z0h_eff_proxy%data, ocn_cpl_point_proxy%data, ndf_wtheta, & &undf_wtheta, map_wtheta, ndf_w3, undf_w3, map_w3, ndf_adspc1_zh, undf_adspc1_zh, map_adspc1_zh, & &ndf_adspc2_tile_fraction, undf_adspc2_tile_fraction, map_adspc2_tile_fraction, ndf_adspc3_leaf_area_index, & @@ -723,7 +722,6 @@ SUBROUTINE invoke_jules_exp_kernel_type(ncells, ncells_halo, theta, exner_in_wth CALL dust_flux_proxy%set_dirty() CALL rhostar_proxy%set_dirty() CALL recip_l_mo_sea_proxy%set_dirty() - CALL h_blend_orog_proxy%set_dirty() CALL t1_sd_2d_proxy%set_dirty() CALL q1_sd_2d_proxy%set_dirty() CALL gross_prim_prod_proxy%set_dirty() diff --git a/interfaces/physics_schemes_interface/source/support/um_physics_init_mod.f90 b/interfaces/physics_schemes_interface/source/support/um_physics_init_mod.f90 index 191a42bce..b1ca9c1fe 100644 --- a/interfaces/physics_schemes_interface/source/support/um_physics_init_mod.f90 +++ b/interfaces/physics_schemes_interface/source/support/um_physics_init_mod.f90 @@ -338,9 +338,8 @@ subroutine um_physics_init() lem_adjust, interactive_fluxes, specified_fluxes_only, & except_disc_inv, ntml_level_corrn, free_trop_layers, sharpest, & lem_stability, sg_shear_enh_lambda, l_new_kcloudtop, buoy_integ, & - l_reset_dec_thres, DynDiag_ZL_CuOnly, var_diags_opt, & - i_interp_local, i_interp_local_gradients, & - split_tke_and_inv, l_noice_in_turb, l_use_var_fixes, & + l_reset_dec_thres, DynDiag_ZL_CuOnly, i_interp_local, & + i_interp_local_gradients, l_noice_in_turb, l_use_var_fixes, & i_interp_local_cf_dbdz, tke_diag_fac, a_ent_2, dec_thres_cloud, & dec_thres_cu, near_neut_z_on_l, blend_gridindep_fa, & specified_fluxes_tstar, buoy_integ_low, num_sweeps_bflux, & @@ -766,10 +765,9 @@ subroutine um_physics_init() sg_orog_mixing = sg_shear_enh_lambda end select - ! Switch for alternative TKE and variance diagnostics - var_diags_opt = split_tke_and_inv - tke_diag_fac = 1.0_r_bl + ! Switch for corrections to variance diagnostics l_use_var_fixes = .true. + tke_diag_fac = 1.0_r_bl zhloc_depth_fac = real(zhloc_depth_fac_in, r_bl) if (topography == topography_horizon) then diff --git a/interfaces/physics_schemes_interface/source/support/um_sizes_init_mod.f90 b/interfaces/physics_schemes_interface/source/support/um_sizes_init_mod.f90 index 26b9fbe43..62942cf9e 100644 --- a/interfaces/physics_schemes_interface/source/support/um_sizes_init_mod.f90 +++ b/interfaces/physics_schemes_interface/source/support/um_sizes_init_mod.f90 @@ -40,8 +40,11 @@ subroutine um_sizes_init(ncells) u_i_length, u_j_length, & v_i_length, v_j_length use tuning_segments_mod, only: bl_segment_size, precip_segment_size, & - ussp_seg_size, gw_seg_size - use physics_config_mod, only : ls_ppn_segment, gw_segment, bl_segment, ussp_segment, configure_segments + ussp_seg_size, gw_seg_size, & + conv_gr_segment_size + use physics_config_mod, only : ls_ppn_segment, gw_segment, & + bl_segment, ussp_segment, & + configure_segments, conv_gr_segment use log_mod, only : log_event, log_scratch_space, LOG_LEVEL_ERROR implicit none @@ -134,12 +137,28 @@ subroutine um_sizes_init(ncells) ussp_seg_size = row_length end select + select case (conv_gr_segment) + case (:-1) + write(log_scratch_space,'(A)') & + 'Invalid value: specified gr_convection segment is -ve.' + call log_event(log_scratch_space, LOG_LEVEL_ERROR) + + case (1:) + ! Set the value from the namelist + conv_gr_segment_size = conv_gr_segment + + case default + ! Default behaviour is to set to row_length + conv_gr_segment_size = row_length + + end select else ! Default behaviour is to set to row_length precip_segment_size = row_length bl_segment_size = row_length gw_seg_size = row_length ussp_seg_size = row_length + conv_gr_segment_size = row_length end if ! Compute lengths in i and j direction. This is the earliest place that they diff --git a/interfaces/physics_schemes_interface/source/support/um_ukca_init_mod.f90 b/interfaces/physics_schemes_interface/source/support/um_ukca_init_mod.f90 index c13d50b8c..351f034ba 100644 --- a/interfaces/physics_schemes_interface/source/support/um_ukca_init_mod.f90 +++ b/interfaces/physics_schemes_interface/source/support/um_ukca_init_mod.f90 @@ -30,7 +30,7 @@ module um_ukca_init_mod top_bdy_opt_overwrt_only_top_lev, & top_bdy_opt_overwrt_co_no_o3_top, & top_bdy_opt_overwrt_co_no_o3_h2o_top, & - ! Variables related to initialisation of photolysis + ! Variables related to initialisation of photolysis photol_scheme, photol_scheme_off, & photol_scheme_fastjx, & photol_scheme_prescribed, fastjx_mode, & @@ -580,7 +580,7 @@ module um_ukca_init_mod integer(kind=i_um), allocatable :: jind(:) ! Index of species from files character(len=photol_jlabel_len), allocatable :: jlabel(:) ! Copy of species ! names to match those from files - real(kind=r_um), pointer :: ratj_jfacta(:) ! Quantum yield + real(kind=r_um), pointer :: ratj_jfacta(:) ! Quantum yield real(kind=r_um), allocatable :: jfacta(:) ! copy of quantum yield in correct units character(len=photol_jlabel_len), allocatable :: titlej(:) @@ -659,7 +659,7 @@ subroutine um_ukca_init(ncells_ukca, model_clock) c3_grass, c4_grass, & shrub, urban, lake, soil, ice - ! UM modules used + ! UM modules used use cv_run_mod, only: l_param_conv implicit none @@ -709,14 +709,14 @@ subroutine um_ukca_init(ncells_ukca, model_clock) if ( chem_timestep < 0_i_def ) then i_chem_timestep = default_chem_timestep - else + else if ( chem_timestep < i_timestep .or. & mod(chem_timestep, i_timestep) /= 0_i_def ) then write(log_scratch_space, '(A,I0,A,A)')'Incorrect chem_timestep found ', & chem_timestep,' This cannot be less than model timestep and has to ', & 'be fully divisible. (Check: namelist:chemistry)' call log_event(log_scratch_space, LOG_LEVEL_ERROR) - else + else i_chem_timestep = int(chem_timestep, i_um) end if end if @@ -848,11 +848,11 @@ subroutine ukca_init( row_length, rows, model_levels, bl_levels, & integer :: i_ukca_light_param=1 ! Internal Price-Rind scheme integer :: i_ukca_quasinewton_start=2, i_ukca_quasinewton_end=3 integer :: i_ukca_scenario=ukca_strat_lbc_env - integer:: i_ukca_mode_seg_size=4 ! GLOMAP-mode segment size - real(r_um) :: linox_scale_in - + integer:: i_ukca_mode_seg_size ! GLOMAP-mode segment size + real(r_um) :: linox_scale_in + character(len=ukca_photol_varname_len) :: adjusted_fname ! intermediate spc/ filename copy - + ! Variables for UKCA error handling integer :: ukca_errcode character(len=ukca_maxlen_message) :: ukca_errmsg @@ -937,8 +937,9 @@ subroutine ukca_init( row_length, rows, model_levels, bl_levels, & end if ! Set default GLOMAP segment size if no factor supplied + i_ukca_mode_seg_size = 4 ! Current working seg size for LFRic if ( ukca_mode_seg_size /= imdi ) THEN - i_ukca_mode_seg_size = ukca_mode_seg_size + i_ukca_mode_seg_size = ukca_mode_seg_size end if call ukca_setup( ukca_errcode, & @@ -1102,7 +1103,7 @@ subroutine ukca_init( row_length, rows, model_levels, bl_levels, & 'Mismatch in expected and registered photolysis reactions: ', & n_phot_spc, jppj,'. Check definitions in ukca_photol_param_mod' call log_event( log_scratch_space, LOG_LEVEL_ERROR ) - end if + end if else if ( photol_scheme == photol_scheme_fastjx ) then ! Read spectral data files, allocate arrays and set up @@ -1122,7 +1123,7 @@ subroutine ukca_init( row_length, rows, model_levels, bl_levels, & jlabel(i)=adjusted_fname(1:photol_jlabel_len) write(log_scratch_space,'(A,I6,E12.3,A12)')'FJX_JFACTA ', i, & jfacta(i),jlabel(i) - call log_event(log_scratch_space, LOG_LEVEL_INFO) + call log_event(log_scratch_space, LOG_LEVEL_INFO) end do ! call wrapper routine that reads FastJX spectral and solar cycle data @@ -1149,11 +1150,11 @@ subroutine ukca_init( row_length, rows, model_levels, bl_levels, & ! include future schemes select case (photol_scheme) case(photol_scheme_fastjx) - i_photol_scheme = photol_fastjx - case default - i_photol_scheme = photol_off + i_photol_scheme = photol_fastjx + case default + i_photol_scheme = photol_off end select - + ! Call Photolysis setup routine to initialise Photolysis ! Hardwired options, CCA field defined on full_face_level_grid, so ! l_3d_cca = .true. and n_cca_lev = number_of_layers (model_levels) @@ -1210,11 +1211,11 @@ subroutine ukca_init( row_length, rows, model_levels, bl_levels, & if (ukca_errcode /= 0) then write( log_scratch_space, '(A,I0,A,A,A,A)' ) 'Photolysis error ', & ukca_errcode, ' in ', ukca_errproc, ': ', ukca_errmsg - call log_event( log_scratch_space, LOG_LEVEL_ERROR ) + call log_event( log_scratch_space, LOG_LEVEL_ERROR ) end if ! Obtain the list of environment fields required by Photolysis n_phot_flds_req = 0 - + call photol_get_environ_varlist(ukca_errcode, & varnames_scalar_real_ptr=photol_fldnames_scalar_real, & varnames_flat_integer_ptr=photol_fldnames_flat_integer, & @@ -1242,7 +1243,7 @@ subroutine ukca_init( row_length, rows, model_levels, bl_levels, & ! Deallocate fastjx spectral data arrays as no longer needed if ( photol_scheme == photol_scheme_fastjx ) & call deallocate_fastjx_filevars() - + end if ! Strattrop and l_ukca_photolysis ! Switch on optional UM microphysics diagnostics required by UKCA @@ -1763,7 +1764,7 @@ subroutine set_ukca_field_lists() end subroutine set_ukca_field_lists subroutine aerosol_ukca_dust_only_init( row_length, rows, model_levels, & - bl_levels, timestep, l_param_conv ) + bl_levels, timestep, l_param_conv ) implicit none @@ -1795,6 +1796,10 @@ subroutine aerosol_ukca_dust_only_init( row_length, rows, model_levels, & character(len=ukca_maxlen_message) :: ukca_errmsg character(len=ukca_maxlen_procname) :: ukca_errproc + ! Some default values - either standard values in UM, or the only ones + ! currently supported in the LFRic-side implementation. + integer:: i_ukca_mode_seg_size ! GLOMAP-mode segment size + ! Set up proto-GA configuration based on GA9. ! The ASAD Newton-Raphson Offline Oxidants scheme (ukca_chem_offline) ! is substituted for the Explicit backward-Euler scheme used in GA9 @@ -1806,6 +1811,12 @@ subroutine aerosol_ukca_dust_only_init( row_length, rows, model_levels, & ! temporary logicals will be on. (i.e. the defaults for these ! logicals, .true. by convention in UKCA, are not overridden.) + ! Set default GLOMAP segment size if no factor supplied + i_ukca_mode_seg_size = 4 ! Current working seg size for LFRic + if ( ukca_mode_seg_size /= imdi ) THEN + i_ukca_mode_seg_size = ukca_mode_seg_size + end if + call ukca_setup( ukca_errcode, & ! Switch to skip setting up constants: these will have already @@ -1842,6 +1853,7 @@ subroutine aerosol_ukca_dust_only_init( row_length, rows, model_levels, & ! General GLOMAP configuration options ! i_mode_nzts=15, & + ukca_mode_seg_size=i_ukca_mode_seg_size, & i_mode_setup=6, & i_mode_nucscav=i_mode_nucscav, & l_cv_rainout=.not.(l_ukca_plume_scav), & @@ -2048,7 +2060,7 @@ subroutine allocate_fastjx_filevars() ! ---------------------------------------------------------------------- ! Description: ! -! allocate arrays that will hold data from FastJX spectral files. +! allocate arrays that will hold data from FastJX spectral files. ! ---------------------------------------------------------------------- implicit none diff --git a/interfaces/physics_schemes_interface/unit-test/kernel/stph/skeb_biharm_diss_kernel_mod_test.pf b/interfaces/physics_schemes_interface/unit-test/kernel/stph/skeb_biharm_diss_kernel_mod_test.pf index 1840b2fee..2060c58b9 100644 --- a/interfaces/physics_schemes_interface/unit-test/kernel/stph/skeb_biharm_diss_kernel_mod_test.pf +++ b/interfaces/physics_schemes_interface/unit-test/kernel/stph/skeb_biharm_diss_kernel_mod_test.pf @@ -7,7 +7,7 @@ !> module skeb_biharm_diss_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, l_def use funit use get_unit_test_m3x3_dofmap_mod, only : get_w2_m3x3_dofmap, & get_w1_m3x3_dofmap, & @@ -69,6 +69,9 @@ contains divergence(:), vorticity(:), ndisp(:) real(r_def), pointer :: norm_xi(:), norm_div(:) + ! Logical controlling whether spectral coeffs need calculating + logical(kind=l_def) :: norm_xi_flag, norm_div_flag + ! Dofmaps integer(i_def), allocatable :: map_w2(:,:), map_w1(:,:), map_w3(:,:), & map_w3_stencil(:,:,:) @@ -112,6 +115,9 @@ contains norm_xi => empty_real_data norm_div => empty_real_data + + norm_xi_flag = .false. + norm_div_flag = .false. dx_at_w2 = 10.0_r_def dt = 3.0_r_def/128.0_r_def @@ -144,6 +150,8 @@ contains 2, 2, dt, & norm_xi, & norm_div, & + norm_xi_flag, & + norm_div_flag, & ndf_w3, & undf_w3, & map_w3(:, cell), & diff --git a/interfaces/socrates_interface/build/import.mk b/interfaces/socrates_interface/build/import.mk index 35e5a09b3..a12f78739 100644 --- a/interfaces/socrates_interface/build/import.mk +++ b/interfaces/socrates_interface/build/import.mk @@ -8,8 +8,7 @@ export PROJECT_SOURCE = $(APPS_ROOT_DIR)/interfaces/socrates_interface/source .PHONY: import-socrates_interface import-socrates_interface: # Get a copy of the source code from the SCORATES repository - python $(APPS_ROOT_DIR)/build/extract/extract_science.py -d $(APPS_ROOT_DIR)/dependencies.yaml -w $(SCRATCH_DIR) -e $(APPS_ROOT_DIR)/interfaces/socrates_interface/build/extract.yaml - $Qrsync -acvz $(SCRATCH_DIR)/socrates $(WORKING_DIR)/ + python $(APPS_ROOT_DIR)/build/extract/extract_science.py -d $(APPS_ROOT_DIR)/dependencies.yaml -w $(WORKING_DIR) -e $(APPS_ROOT_DIR)/interfaces/socrates_interface/build/extract.yaml # Extract the interface code $Q$(MAKE) $(QUIET_ARG) -f $(LFRIC_BUILD)/extract.mk \ diff --git a/interfaces/socrates_interface/rose-meta/socrates-radiation/HEAD/rose-meta.conf b/interfaces/socrates_interface/rose-meta/socrates-radiation/HEAD/rose-meta.conf index 43f642ccb..4385576ff 100644 --- a/interfaces/socrates_interface/rose-meta/socrates-radiation/HEAD/rose-meta.conf +++ b/interfaces/socrates_interface/rose-meta/socrates-radiation/HEAD/rose-meta.conf @@ -15,14 +15,23 @@ description=Run COSP if diagnostics are requested !kind=default ns=namelist/Science/SOCRATES COSP sort-key=Panel-A01 -trigger=namelist:cosp=n_subcol_gen: .true. ; +trigger=namelist:cosp=n_cosp_step: .true. ; + =namelist:cosp=n_subcol_gen: .true. ; type=logical +[namelist:cosp=n_cosp_step] +compulsory=true +description=Number of model timesteps per COSP diagnostic sampling +help=COSP will use a sunlit mask based on the length of the COSP timestep. +!kind=default +sort-key=Panel-A02 +type=integer + [namelist:cosp=n_subcol_gen] compulsory=true description=Number of sub-columns for the cloud generator !kind=default -sort-key=Panel-A02 +sort-key=Panel-A03 type=integer #============================================================================== diff --git a/interfaces/socrates_interface/rose-meta/socrates-radiation/version30_31.py b/interfaces/socrates_interface/rose-meta/socrates-radiation/version30_31.py new file mode 100644 index 000000000..dc8f5b2db --- /dev/null +++ b/interfaces/socrates_interface/rose-meta/socrates-radiation/version30_31.py @@ -0,0 +1,55 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + return config, self.reports diff --git a/interfaces/socrates_interface/rose-meta/socrates-radiation/versions.py b/interfaces/socrates_interface/rose-meta/socrates-radiation/versions.py index 152c043d0..01798ad2b 100644 --- a/interfaces/socrates_interface/rose-meta/socrates-radiation/versions.py +++ b/interfaces/socrates_interface/rose-meta/socrates-radiation/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/interfaces/socrates_interface/rose-meta/socrates-radiation/vn3.1/rose-meta.conf b/interfaces/socrates_interface/rose-meta/socrates-radiation/vn3.1/rose-meta.conf new file mode 100644 index 000000000..4385576ff --- /dev/null +++ b/interfaces/socrates_interface/rose-meta/socrates-radiation/vn3.1/rose-meta.conf @@ -0,0 +1,1950 @@ +#============================================================================== +# COSP +#============================================================================== + +[namelist:cosp] +compulsory=true +description=Options for the CFMIP Observation Simulator Package (COSP) +ns=namelist/Science/SOCRATES COSP +sort-key=Section-A20 +title=COSP + +[namelist:cosp=l_cosp] +compulsory=true +description=Run COSP if diagnostics are requested +!kind=default +ns=namelist/Science/SOCRATES COSP +sort-key=Panel-A01 +trigger=namelist:cosp=n_cosp_step: .true. ; + =namelist:cosp=n_subcol_gen: .true. ; +type=logical + +[namelist:cosp=n_cosp_step] +compulsory=true +description=Number of model timesteps per COSP diagnostic sampling +help=COSP will use a sunlit mask based on the length of the COSP timestep. +!kind=default +sort-key=Panel-A02 +type=integer + +[namelist:cosp=n_subcol_gen] +compulsory=true +description=Number of sub-columns for the cloud generator +!kind=default +sort-key=Panel-A03 +type=integer + +#============================================================================== +# RADIATION +#============================================================================== +[namelist:radiation] +compulsory=true +description=Radiation scheme options +ns=namelist/Science/SOCRATES Radiation +sort-key=Section-A10 +title=Radiation + +[namelist:radiation=cloud_entrapment] +compulsory=true +description=Treatment of flux entrapment by cloud layers +!enumeration=true +help=This option determines the solver used for radiative transfer between + =fractional cloud layers when not using McICA. There are two options: + =_________________________________________________________________ + =Maximum + = Maximum entrapment: fluxes are horizontally homogenised within + = cloud or clear-sky regions and may be reflected back up into + = different regions. + =_________________________________________________________________ + =Zero + = Zero entrapment: fluxes exiting the base of a given region may + = only be reflected back up into the same region. +sort-key=Panel-A04a +value-titles=Maximum, Zero +values='max','zero' + +[namelist:radiation=cloud_inhomogeneity] +compulsory=true +description=Sub-grid cloud horizontal inhomogeneity +!enumeration=true +help=Cloud water content exhibits subgrid-scale variability. The options for + =reperesenting the radiative effects of this variability are as follows: + =_________________________________________________________________ + =Homogeneous + = Horizontal water content variability is ignored. + =_________________________________________________________________ + =Scaling + = The mean water content in each gridbox is multiplied by given + = scaling factors. + =_________________________________________________________________ + =MCICA + = A stochastic cloud generator is used to produce sub-columns + = containing different water content values, which are randomly sampled. + =_________________________________________________________________ + =Cairns + = A correction is applied to the optical scattering properties to + = account for cloud inhomogeneity based on Cairns et al. (2000) JAS, 57. + =_________________________________________________________________ + =Tripleclouds + = Split cloud into optically thick and thin regions using the + = parametrisation from Hogan et al. (2019) DOI:10.1175/JAS-D-18-0366.1 +sort-key=Panel-A04 +trigger=namelist:radiation=cloud_entrapment: 'homogeneous', 'scaling', + ='cairns', 'tripleclouds' ; +value-titles=Homogeneous, Scaling factor, MCICA, Cairns et. al. 2000, + =Tripleclouds +values='homogeneous', 'scaling', 'mcica', 'cairns', 'tripleclouds' + +[namelist:radiation=cloud_overlap] +compulsory=true +description=Cloud fraction vertical overlap +!enumeration=true +help=Options for treating the vertical overlap between different cloud + =layers: + =_________________________________________________________________ + =Maximum-Random + = Clouds in adjacent layers are maximally overlapped. + = Clouds separated by clear-sky are randomly overlapped. + =_________________________________________________________________ + =Random + = All clouds are randomly overlapped. + =_________________________________________________________________ + =Exponential-Random + = For clouds in adjacent layers the overlap is a linear combination + = of maximum and random. The parameter controlling the proportion + = of each depends on the decorrelation pressure scale(s). +sort-key=Panel-A03 +trigger=namelist:radiation=cloud_vertical_decorr: 'exponential_random' ; +value-titles=Maximum-Random, Random, Exponential-Random +values='maximum_random', 'random', 'exponential_random' + +[namelist:radiation=cloud_representation] +compulsory=true +description=Representation of cloud +!enumeration=true +help=Mixed-phase clouds contain both ice crystals and water droplets. + =For the current options these are represented as being + =segregated into separate sub-clouds placed side by side. + =The clouds may be further divided into one or two regions to + =represent either separate convective and large-scale cloud + =fractions or optically thick and thin regions depending on the + =following options: + =_________________________________________________________________ + =No cloud + = Cloud has no radiative effect. + =_________________________________________________________________ + =Large-scale cloud only + = Single cloud region containing only large-scale liquid and ice. + =_________________________________________________________________ + =Combined convective and large-scale cloud + = Single cloud region including contributions from convective + = and large-scale cloud liquid and ice. + =_________________________________________________________________ + =Segregated large-scale and convective cloud + = Two cloud regions: one region containing convective liquid and + = ice and a second region containing large-scale liquid and ice. + =_________________________________________________________________ + =Combined cloud split into thick and thin regions + = Two cloud regions: both regions contain contributions from + = convective and large-scale cloud. Condensate is proportioned + = between an optically thick and an optically thin region + = depending on the cloud_inhomogeneity option. +sort-key=Panel-A02 +trigger=namelist:radiation=cloud_overlap: 'liquid_and_ice', + ='combined', 'conv_strat_liq_ice', 'split' ; + =namelist:radiation=cloud_inhomogeneity: 'liquid_and_ice', + ='combined', 'conv_strat_liq_ice', 'split' ; + =namelist:radiation=droplet_effective_radius: 'liquid_and_ice', + ='combined', 'conv_strat_liq_ice', 'split' ; +value-titles=No cloud, + =Large-scale cloud only, + =Combined convective and large-scale cloud, + =Segregated large-scale and convective cloud, + =Combined cloud split into thick and thin regions +values='no_cloud', 'liquid_and_ice', 'combined', 'conv_strat_liq_ice', 'split' + +[namelist:radiation=cloud_vertical_decorr] +compulsory=true +description=Decorrelation pressure scale for cloud vertical overlap +help=Defines the sub-grid cloud vertical overlap using a single + =global value of the decorrelation pressure scale (Pa). + =This is the pressure difference over which the extent of vertical + =overlap of sub-grid cloud fraction falls to 1/e. +!kind=default +sort-key=Panel-A03a +type=real + +[namelist:radiation=constant_droplet_effective_radius] +compulsory=true +description=Cloud droplet effective radius +help=Value of constant cloud droplet effective radius in metres. +!kind=default +sort-key=Panel-A05a +type=real + +[namelist:radiation=droplet_effective_radius] +compulsory=true +description=Treatment of cloud droplet effective radius +!enumeration=true +help=Options for setting the cloud droplet effective radius: + =_________________________________________________________________ + =Default + = Use the Socrates default value of 7 microns. + =_________________________________________________________________ + =Constant + = Use the constant value: constant_droplet_effective_radius + =_________________________________________________________________ + =Liu Spectral Dispersion + = Use the relative spectral dispersion parameterization of + = Liu et al (2008), ERL. + = The relative dispersion used in the calculation of cloud + = droplet effective radius is calculated as a function of + = cloud liquid water and droplet number concentration. +sort-key=Panel-A05 +trigger=namelist:radiation=constant_droplet_effective_radius: 'constant' ; + =namelist:radiation=liu_aparam: 'liu' ; + =namelist:radiation=liu_bparam: 'liu' ; +value-titles=Default (7 micron), + =Constant, + =Liu Spectral Dispersion +values='default', 'constant', 'liu' + +[namelist:radiation=i_cloud_ice_type_lw] +compulsory=true +description=Type of optical properties for cloud ice +help=Type number for the ice-crystal optical properties + =selected from those present in the LW spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Long-Wave +sort-key=Panel-A01b +type=integer + +[namelist:radiation=i_cloud_ice_type_lwinc] +compulsory=true +description=Type of optical properties for cloud ice increments +help=Type number for the ice-crystal optical properties + =selected from those present in the LW increment spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Long-Wave Increment +sort-key=Panel-A01b +type=integer + +[namelist:radiation=i_cloud_ice_type_sw] +compulsory=true +description=Type of optical properties for cloud ice +help=Type number for the ice-crystal optical properties + =selected from those present in the SW spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Short-Wave +sort-key=Panel-A01b +type=integer + +[namelist:radiation=i_cloud_ice_type_swinc] +compulsory=true +description=Type of optical properties for cloud ice increments +help=Type number for the ice-crystal optical properties + =selected from those present in the SW increment spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Short-Wave Increment +sort-key=Panel-A01b +type=integer + +[namelist:radiation=i_cloud_liq_type_lw] +compulsory=true +description=Type of optical properties for cloud liquid +help=Type number for the cloud liquid optical properties + =selected from those present in the LW spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Long-Wave +sort-key=Panel-A01a +type=integer + +[namelist:radiation=i_cloud_liq_type_lwinc] +compulsory=true +description=Type of optical properties for cloud liquid increments +help=Type number for the cloud liquid optical properties + =selected from those present in the LW increment spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Long-Wave Increment +sort-key=Panel-A01a +type=integer + +[namelist:radiation=i_cloud_liq_type_sw] +compulsory=true +description=Type of optical properties for cloud liquid +help=Type number for the cloud liquid optical properties + =selected from those present in the SW spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Short-Wave +sort-key=Panel-A01a +type=integer + +[namelist:radiation=i_cloud_liq_type_swinc] +compulsory=true +description=Type of optical properties for cloud liquid increments +help=Type number for the cloud liquid optical properties + =selected from those present in the SW increment spectral file. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Short-Wave Increment +sort-key=Panel-A01a +type=integer + +[namelist:radiation=l_inc_radstep] +compulsory=true +description=Apply incremental radiation timesteps +help=Simple radiation increments may be calculated more frequently + =than full radiation calculations. This is generally applied to + =account for changes in low cloud. +!kind=default +sort-key=Panel-A00a +trigger=namelist:radiation=i_cloud_ice_type_lwinc: .true. ; + =namelist:radiation=i_cloud_ice_type_swinc: .true. ; + =namelist:radiation=i_cloud_liq_type_lwinc: .true. ; + =namelist:radiation=i_cloud_liq_type_swinc: .true. ; + =namelist:radiation=n_inc_radstep: .true. ; + =namelist:radiation=scatter_method_lwinc: .true. ; + =namelist:radiation=spectral_file_lwinc: .true. ; + =namelist:radiation=spectral_file_swinc: .true. ; +type=logical + +[namelist:radiation=l_planet_grey_surface] +compulsory=true +description=Set grey surface optical properties +help=Grey surface with constant shortwave albedo + =and longwave emissivity for all points. +!kind=default +sort-key=Panel-A01 +trigger=namelist:radiation=planet_albedo: .true. ; + =namelist:radiation=planet_emissivity: .true. ; + =namelist:specified_surface=surf_temp_forcing: .true. ; +type=logical + +[namelist:radiation=l_rayleigh_sw] +compulsory=true +description=Include Rayleigh scattering +!kind=default +ns=namelist/Science/SOCRATES Radiation/Short-Wave +sort-key=Panel-A02 +type=logical + +[namelist:radiation=l_trans_zen_correction] +compulsory=true +description=Transmission based solar zenith angle correction +help=This will take into account the change in optical path length through the + =atmosphere when correcting the surface fluxes for the change in + =solar zenith angle between radiation time-steps. See Manners et al 2009, + =DOI:10.1002/qj.385 for further details. +!kind=default +ns=namelist/Science/SOCRATES Radiation/Short-Wave +sort-key=Panel-A01c +type=logical + +[namelist:radiation=liu_aparam] +compulsory=true +description=Parameter A for Liu spectral dispersion +help=Parameter to control the cloud droplet effective radius as a function of the cloud droplet number concentration. +!kind=default +sort-key=Panel-A05a +type=real + +[namelist:radiation=liu_bparam] +compulsory=true +description=Parameter B for Liu spectral dispersion +help=Parameter to control the cloud droplet effective radius as a function of the cloud droplet number concentration. +!kind=default +sort-key=Panel-A05b +type=real + +[namelist:radiation=mcica_data_file] +compulsory=true +description=MCICA data file +help=The path to the MCICA data file holding the configuration for sampling + =sub-grid cloud. This file is specific to the particular SW and LW + =spectral files used in the run and will usually be held in the same + =directory as the spectral files. +sort-key=Panel-A04b +!string_length=filename +type=character + +[namelist:radiation=n_horiz_ang] +compulsory=true +description=Number of aspects of horizon angles +help=Number of directions in which horizon angles are supplied in + =the ancillary data. +!kind=default +sort-key=Panel-A06a +type=integer + +[namelist:radiation=n_horiz_layer] +compulsory=true +description=Number of layers of horizon angles +help=Number of model layers (including the surface) in which horizon + =angles are supplied in the ancillary data. +!kind=default +sort-key=Panel-A06b +type=integer + +[namelist:radiation=n_inc_radstep] +compulsory=true +description=Number of model timesteps per increment radiation timestep +help=The increment radiation calculations should be done more frequently + =then every radiation timestep. Increment calculations will be done + =on timesteps 1, 1+n_inc_radstep, 1+n_inc_radstep*2... +!kind=default +sort-key=Panel-A00b +type=integer + +[namelist:radiation=n_radstep] +compulsory=true +description=Number of model timesteps per radiation timestep +help=The radiation calculations may be done less frequently than + =every model (dynamics) timestep. Radiation calculations will + =be done on timesteps 1, 1+n_radstep, 1+n_radstep*2... +!kind=default +sort-key=Panel-A00 +type=integer + +[namelist:radiation=planet_albedo] +compulsory=true +description=Grey surface shortwave albedo +help=Surface albedo for all points and all wavelengths. +!kind=default +sort-key=Panel-A01a +type=real + +[namelist:radiation=planet_emissivity] +compulsory=true +description=Grey surface longwave emissivity +help=Surface emissivity for all points and all wavelengths. +!kind=default +sort-key=Panel-A01b +type=real + +[namelist:radiation=scatter_method_lw] +compulsory=true +description=Treatment of scattering for longwave optical properties +!enumeration=true +help=Treatment of scattering for longwave optical properties. + =Approximate and hybrid methods are faster but less accurate. + =The hybrid method uses a different treatment of scattering for each + =k-term and requires the methods to be set in the spectral file. +ns=namelist/Science/SOCRATES Radiation/Long-Wave +sort-key=Panel-A010 +value-titles=Full,None,Approximate,Hybrid +values='full','none','approx','hybrid' + +[namelist:radiation=scatter_method_lwinc] +compulsory=true +description=Treatment of scattering for longwave increments +!enumeration=true +help=Treatment of scattering for longwave increments + =Approximate and hybrid methods are faster but less accurate. + =The hybrid method uses a different treatment of scattering for each + =k-term and requires the methods to be set in the spectral file. +ns=namelist/Science/SOCRATES Radiation/Long-Wave Increment +sort-key=Panel-A010 +value-titles=Full,None,Approximate,Hybrid +values='full','none','approx','hybrid' + +[namelist:radiation=spectral_file_lw] +compulsory=true +description=Longwave spectral file +help=The path to the longwave spectral file holding the configuration of + =optical properties for the longwave radiation calculation. +ns=namelist/Science/SOCRATES Radiation/Long-Wave +sort-key=Panel-A01 +!string_length=filename +type=character + +[namelist:radiation=spectral_file_lwinc] +compulsory=true +description=Increment longwave spectral file +help=The path to the longwave spectral file holding the configuration of + =optical properties for the incremental longwave radiation calculation. +ns=namelist/Science/SOCRATES Radiation/Long-Wave Increment +sort-key=Panel-A01 +!string_length=filename +type=character + +[namelist:radiation=spectral_file_sw] +compulsory=true +description=Shortwave spectral file +help=The path to the shortwave spectral file holding the configuration of + =optical properties for the shortwave (SW) radiation calculation. +ns=namelist/Science/SOCRATES Radiation/Short-Wave +sort-key=Panel-A01 +!string_length=filename +type=character + +[namelist:radiation=spectral_file_swinc] +compulsory=true +description=Increment shortwave spectral file +help=The path to the shortwave spectral file holding the configuration of + =optical properties for the incremental shortwave radiation calculation. +ns=namelist/Science/SOCRATES Radiation/Short-Wave Increment +sort-key=Panel-A01 +!string_length=filename +type=character + +[namelist:radiation=topography] +compulsory=true +description=Topographic correction scheme +!enumeration=true +help=Treatment of radiative transfer over resolved topographic features: + =_________________________________________________________________ + =Flat + = No corrections for slope or shading + =_________________________________________________________________ + =Slope + = Corrects the direct SW radiation absorbed and reflected at the + = surface for the angle of the surface slope with respect to the + = position of the sun. + = + = Requires that X and Y gradient fields are read from the + = orography ancillary file. + =_________________________________________________________________ + =Horizon + = In addition to the treatment of surface slope, the direct SW + = radiation at the surface will also be corrected for shading by + = surrounding terrain. The insulating effect of surrounding + = terrain on the LW net surface flux will be accounted for in + = the absorbed land surface flux (within JULES). + = + = Requires that horizon angle and aspect fields are read from the + = orography ancillary file. + = + =Manners et. al. (2012), DOI:10.1002/qj.956 +sort-key=Panel-A06 +trigger=namelist:radiation=n_horiz_ang: 'horizon' ; + =namelist:radiation=n_horiz_layer: 'horizon' ; +value-titles=Flat, Slope, Horizon +values='flat', 'slope', 'horizon' + +#============================================================================== +# RADIATIVELY ACTIVE GASES +#============================================================================== +[namelist:radiative_gases] +compulsory=true +description=Mass mixing ratios of radiatively active gases [kg/kg] +help=Settings for the gas mass mixing ratios to be used in + =the radiative transfer calculations. + = + =When the 'time_varying' option is used: + = If a negative rate is specified in the *_clim_fcg_rates parameter + = gas concentrations will be linearly interpolated between given values. + = Where positive rates are supplied the current gas concentration will + = be calculated by compounding the rates given for each year. + = This means only the concentration supplied for the first year of the + = positive sequence will be used. +ns=namelist/Science/SOCRATES Radiation/Gases +sort-key=Section-A01b +title=Radiatively active gases + +[namelist:radiative_gases=cfc113_clim_fcg_levls] +compulsory=true +description=List of values for growth for the CFC113 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A01c +type=real + +[namelist:radiative_gases=cfc113_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the CFC113 gas +sort-key=Panel-A01d +type=integer + +[namelist:radiative_gases=cfc113_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the CFC113 gas +length=: +sort-key=Panel-A01e +type=real + +[namelist:radiative_gases=cfc113_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas CFC113 +length=: +sort-key=Panel-A01f +type=integer + +[namelist:radiative_gases=cfc113_mix_ratio] +compulsory=true +description=CFC113 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A01b +type=real + +[namelist:radiative_gases=cfc113_rad_opt] +compulsory=true +description=Radiative options for CFC113 +!enumeration=true +help=RT options for the mixing ratio of CFC113 +sort-key=Panel-A01a +trigger=namelist:radiative_gases=cfc113_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=cfc113_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=cfc113_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=cfc113_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=cfc113_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value +values='off', 'constant', 'time_varying' + +[namelist:radiative_gases=cfc11_clim_fcg_levls] +compulsory=true +description=List of values for growth for the CFC11 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A00c +type=real + +[namelist:radiative_gases=cfc11_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the CFC11 gas +sort-key=Panel-A00d +type=integer + +[namelist:radiative_gases=cfc11_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the CFC11 gas +length=: +sort-key=Panel-A00e +type=real + +[namelist:radiative_gases=cfc11_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas CFC11 +length=: +sort-key=Panel-A00f +type=integer + +[namelist:radiative_gases=cfc11_mix_ratio] +compulsory=true +description=CFC11 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A00b +type=real + +[namelist:radiative_gases=cfc11_rad_opt] +compulsory=true +description=Radiative options for CFC11 +!enumeration=true +help=RT options for the mixing ratio of CFC11 +sort-key=Panel-A00a +trigger=namelist:radiative_gases=cfc11_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=cfc11_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=cfc11_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=cfc11_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=cfc11_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value +values='off', 'constant', 'time_varying' + +[namelist:radiative_gases=cfc12_clim_fcg_levls] +compulsory=true +description=List of values for growth for the CFC12 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A02c +type=real + +[namelist:radiative_gases=cfc12_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the CFC12 gas +sort-key=Panel-A02d +type=integer + +[namelist:radiative_gases=cfc12_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the CFC12 gas +length=: +sort-key=Panel-A02e +type=real + +[namelist:radiative_gases=cfc12_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas CFC12 +length=: +sort-key=Panel-A02f +type=integer + +[namelist:radiative_gases=cfc12_mix_ratio] +compulsory=true +description=CFC12 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A02b +type=real + +[namelist:radiative_gases=cfc12_rad_opt] +compulsory=true +description=Radiative options for CFC12 +!enumeration=true +help=RT options for the mixing ratio of CFC12 +sort-key=Panel-A02a +trigger=namelist:radiative_gases=cfc12_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=cfc12_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=cfc12_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=cfc12_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=cfc12_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value +values='off', 'constant', 'time_varying' + +[namelist:radiative_gases=ch4_clim_fcg_levls] +compulsory=true +description=List of values for growth for the CH4 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A03c +type=real + +[namelist:radiative_gases=ch4_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the CH4 gas +sort-key=Panel-A03d +type=integer + +[namelist:radiative_gases=ch4_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the CH4 gas +length=: +sort-key=Panel-A03e +type=real + +[namelist:radiative_gases=ch4_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas CH4 +length=: +sort-key=Panel-A03f +type=integer + +[namelist:radiative_gases=ch4_mix_ratio] +compulsory=true +description=CH4 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A03b +type=real + +[namelist:radiative_gases=ch4_rad_opt] +compulsory=true +description=Radiative options for CH4 +!enumeration=true +help=RT options for the mixing ratio of CH4 +sort-key=Panel-A03a +trigger=namelist:radiative_gases=ch4_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=ch4_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=ch4_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=ch4_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=ch4_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=co2_clim_fcg_levls] +compulsory=true +description=List of values for growth for the CO2 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A05c +type=real + +[namelist:radiative_gases=co2_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the CO2 gas +sort-key=Panel-A05d +type=integer + +[namelist:radiative_gases=co2_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the CO2 gas +length=: +sort-key=Panel-A05e +type=real + +[namelist:radiative_gases=co2_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas CO2 +length=: +sort-key=Panel-A05f +type=integer + +[namelist:radiative_gases=co2_mix_ratio] +compulsory=true +description=CO2 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A05b +type=real + +[namelist:radiative_gases=co2_rad_opt] +compulsory=true +description=Radiative options for CO2 +!enumeration=true +help=RT options for the mixing ratio of CO2 +sort-key=Panel-A05a +trigger=namelist:radiative_gases=co2_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=co2_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=co2_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=co2_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=co2_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=co_clim_fcg_levls] +compulsory=true +description=List of values for growth for the CO gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A04c +type=real + +[namelist:radiative_gases=co_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the CO gas +sort-key=Panel-A04d +type=integer + +[namelist:radiative_gases=co_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the CO gas +length=: +sort-key=Panel-A04e +type=real + +[namelist:radiative_gases=co_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas CO +length=: +sort-key=Panel-A04f +type=integer + +[namelist:radiative_gases=co_mix_ratio] +compulsory=true +description=CO mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A04b +type=real + +[namelist:radiative_gases=co_rad_opt] +compulsory=true +description=Radiative options for CO +!enumeration=true +help=RT options for the mixing ratio of CO +sort-key=Panel-A04a +trigger=namelist:radiative_gases=co_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=co_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=co_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=co_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=co_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=cs_clim_fcg_levls] +compulsory=true +description=List of values for growth for the Cs gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A18c +type=real + +[namelist:radiative_gases=cs_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the Cs gas +sort-key=Panel-A18d +type=integer + +[namelist:radiative_gases=cs_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the Cs gas +length=: +sort-key=Panel-A18e +type=real + +[namelist:radiative_gases=cs_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas Cs +length=: +sort-key=Panel-A18f +type=integer + +[namelist:radiative_gases=cs_mix_ratio] +compulsory=true +description=Cs mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A18b +type=real + +[namelist:radiative_gases=cs_rad_opt] +compulsory=true +description=Radiative options for Cs +!enumeration=true +help=RT options for the mixing ratio of Cs +sort-key=Panel-A18a +trigger=namelist:radiative_gases=cs_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=cs_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=cs_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=cs_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=cs_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=h2_clim_fcg_levls] +compulsory=true +description=List of values for growth for the H2 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A06c +type=real + +[namelist:radiative_gases=h2_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the H2 gas +sort-key=Panel-A06d +type=integer + +[namelist:radiative_gases=h2_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the H2 gas +length=: +sort-key=Panel-A06e +type=real + +[namelist:radiative_gases=h2_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas H2 +length=: +sort-key=Panel-A06f +type=integer + +[namelist:radiative_gases=h2_mix_ratio] +compulsory=true +description=H2 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A06b +type=real + +[namelist:radiative_gases=h2_rad_opt] +compulsory=true +description=Radiative options for H2 +!enumeration=true +help=RT options for the mixing ratio of H2 +sort-key=Panel-A06a +trigger=namelist:radiative_gases=h2_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=h2_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=h2_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=h2_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=h2_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=h2o_clim_fcg_levls] +compulsory=true +description=List of values for growth for the H2O gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A07c +type=real + +[namelist:radiative_gases=h2o_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the H2O gas +sort-key=Panel-A07d +type=integer + +[namelist:radiative_gases=h2o_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the H2O gas +length=: +sort-key=Panel-A07e +type=real + +[namelist:radiative_gases=h2o_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas H2O +length=: +sort-key=Panel-A07f +type=integer + +[namelist:radiative_gases=h2o_mix_ratio] +compulsory=true +description=H2O mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A07b +type=real + +[namelist:radiative_gases=h2o_rad_opt] +compulsory=true +description=Radiative options for H2O +!enumeration=true +help=RT options for the mixing ratio of H2O +sort-key=Panel-A07a +trigger=namelist:radiative_gases=h2o_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=h2o_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=h2o_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=h2o_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=h2o_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=hcfc22_clim_fcg_levls] +compulsory=true +description=List of values for growth for the HCFC22 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A08c +type=real + +[namelist:radiative_gases=hcfc22_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the HCFC22 gas +sort-key=Panel-A08d +type=integer + +[namelist:radiative_gases=hcfc22_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the HCFC22 gas +length=: +sort-key=Panel-A08e +type=real + +[namelist:radiative_gases=hcfc22_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas HCFC22 +length=: +sort-key=Panel-A08f +type=integer + +[namelist:radiative_gases=hcfc22_mix_ratio] +compulsory=true +description=HCFC22 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A08b +type=real + +[namelist:radiative_gases=hcfc22_rad_opt] +compulsory=true +description=Radiative options for HCFC22 +!enumeration=true +help=RT options for the mixing ratio of HCFC22 +sort-key=Panel-A08a +trigger=namelist:radiative_gases=hcfc22_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=hcfc22_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=hcfc22_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=hcfc22_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=hcfc22_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value +values='off', 'constant', 'time_varying' + +[namelist:radiative_gases=hcn_clim_fcg_levls] +compulsory=true +description=List of values for growth for the HCN gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A09c +type=real + +[namelist:radiative_gases=hcn_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the HCN gas +sort-key=Panel-A09d +type=integer + +[namelist:radiative_gases=hcn_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the HCN gas +length=: +sort-key=Panel-A09e +type=real + +[namelist:radiative_gases=hcn_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas HCN +length=: +sort-key=Panel-A09f +type=integer + +[namelist:radiative_gases=hcn_mix_ratio] +compulsory=true +description=HCN mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A09b +type=real + +[namelist:radiative_gases=hcn_rad_opt] +compulsory=true +description=Radiative options for HCN +!enumeration=true +help=RT options for the mixing ratio of HCN +sort-key=Panel-A09a +trigger=namelist:radiative_gases=hcn_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=hcn_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=hcn_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=hcn_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=hcn_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=he_clim_fcg_levls] +compulsory=true +description=List of values for growth for the HE gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A10c +type=real + +[namelist:radiative_gases=he_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the HE gas +sort-key=Panel-A10d +type=integer + +[namelist:radiative_gases=he_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the HE gas +length=: +sort-key=Panel-A10e +type=real + +[namelist:radiative_gases=he_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas HE +length=: +sort-key=Panel-A10f +type=integer + +[namelist:radiative_gases=he_mix_ratio] +compulsory=true +description=HE mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A10b +type=real + +[namelist:radiative_gases=he_rad_opt] +compulsory=true +description=Radiative options for HE +!enumeration=true +help=RT options for the mixing ratio of HE +sort-key=Panel-A10a +trigger=namelist:radiative_gases=he_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=he_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=he_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=he_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=he_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=hfc134a_clim_fcg_levls] +compulsory=true +description=List of values for growth for the HFC134A gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A11c +type=real + +[namelist:radiative_gases=hfc134a_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the HFC134A gas +sort-key=Panel-A11d +type=integer + +[namelist:radiative_gases=hfc134a_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the HFC134A gas +length=: +sort-key=Panel-A11e +type=real + +[namelist:radiative_gases=hfc134a_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas HFC134A +length=: +sort-key=Panel-A11f +type=integer + +[namelist:radiative_gases=hfc134a_mix_ratio] +compulsory=true +description=HFC134A mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A11b +type=real + +[namelist:radiative_gases=hfc134a_rad_opt] +compulsory=true +description=Radiative options for HFC134A +!enumeration=true +help=RT options for the mixing ratio of HFC134A +sort-key=Panel-A11a +trigger=namelist:radiative_gases=hfc134a_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=hfc134a_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=hfc134a_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=hfc134a_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=hfc134a_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value +values='off', 'constant', 'time_varying' + +[namelist:radiative_gases=k_clim_fcg_levls] +compulsory=true +description=List of values for growth for the K gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A19c +type=real + +[namelist:radiative_gases=k_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the K gas +sort-key=Panel-A19d +type=integer + +[namelist:radiative_gases=k_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the K gas +length=: +sort-key=Panel-A19e +type=real + +[namelist:radiative_gases=k_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas K +length=: +sort-key=Panel-A19f +type=integer + +[namelist:radiative_gases=k_mix_ratio] +compulsory=true +description=K mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A19b +type=real + +[namelist:radiative_gases=k_rad_opt] +compulsory=true +description=Radiative options for K +!enumeration=true +help=RT options for the mixing ratio of K +sort-key=Panel-A19a +trigger=namelist:radiative_gases=k_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=k_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=k_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=k_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=k_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=l_cts_fcg_rates] +compulsory=true +description=If using time-varying gases with rates, then switch + =this on so that gas rates are applied continuously + =rather than updating at the beginning of the year +sort-key=Panel-A99 +type=logical + +[namelist:radiative_gases=li_clim_fcg_levls] +compulsory=true +description=List of values for growth for the Li gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A20c +type=real + +[namelist:radiative_gases=li_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the Li gas +sort-key=Panel-A20d +type=integer + +[namelist:radiative_gases=li_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the Li gas +length=: +sort-key=Panel-A20e +type=real + +[namelist:radiative_gases=li_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas Li +length=: +sort-key=Panel-A20f +type=integer + +[namelist:radiative_gases=li_mix_ratio] +compulsory=true +description=Li mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A20b +type=real + +[namelist:radiative_gases=li_rad_opt] +compulsory=true +description=Radiative options for Li +!enumeration=true +help=RT options for the mixing ratio of Li +sort-key=Panel-A20a +trigger=namelist:radiative_gases=li_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=li_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=li_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=li_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=li_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=n2_clim_fcg_levls] +compulsory=true +description=List of values for growth for the N2 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A12c +type=real + +[namelist:radiative_gases=n2_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the N2 gas +sort-key=Panel-A12d +type=integer + +[namelist:radiative_gases=n2_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the N2 gas +length=: +sort-key=Panel-A12e +type=real + +[namelist:radiative_gases=n2_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas N2 +length=: +sort-key=Panel-A12f +type=integer + +[namelist:radiative_gases=n2_mix_ratio] +compulsory=true +description=N2 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A12b +type=real + +[namelist:radiative_gases=n2_rad_opt] +compulsory=true +description=Radiative options for N2 +!enumeration=true +help=RT options for the mixing ratio of N2 +sort-key=Panel-A12a +trigger=namelist:radiative_gases=n2_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=n2_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=n2_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=n2_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=n2_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=n2o_clim_fcg_levls] +compulsory=true +description=List of values for growth for the N2O gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A13c +type=real + +[namelist:radiative_gases=n2o_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the N2O gas +sort-key=Panel-A13d +type=integer + +[namelist:radiative_gases=n2o_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the N2O gas +length=: +sort-key=Panel-A13e +type=real + +[namelist:radiative_gases=n2o_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas N2O +length=: +sort-key=Panel-A13f +type=integer + +[namelist:radiative_gases=n2o_mix_ratio] +compulsory=true +description=N2O mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A13b +type=real + +[namelist:radiative_gases=n2o_rad_opt] +compulsory=true +description=Radiative options for N2O +!enumeration=true +help=RT options for the mixing ratio of N2O +sort-key=Panel-A13a +trigger=namelist:radiative_gases=n2o_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=n2o_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=n2o_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=n2o_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=n2o_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=na_clim_fcg_levls] +compulsory=true +description=List of values for growth for the Na gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A21c +type=real + +[namelist:radiative_gases=na_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the Na gas +sort-key=Panel-A21d +type=integer + +[namelist:radiative_gases=na_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the Na gas +length=: +sort-key=Panel-A21e +type=real + +[namelist:radiative_gases=na_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas Na +length=: +sort-key=Panel-A21f +type=integer + +[namelist:radiative_gases=na_mix_ratio] +compulsory=true +description=Na mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A21b +type=real + +[namelist:radiative_gases=na_rad_opt] +compulsory=true +description=Radiative options for Na +!enumeration=true +help=RT options for the mixing ratio of Na +sort-key=Panel-A21a +trigger=namelist:radiative_gases=na_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=na_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=na_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=na_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=na_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=nh3_clim_fcg_levls] +compulsory=true +description=List of values for growth for the NH3 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A14c +type=real + +[namelist:radiative_gases=nh3_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the NH3 gas +sort-key=Panel-A14d +type=integer + +[namelist:radiative_gases=nh3_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the NH3 gas +length=: +sort-key=Panel-A14e +type=real + +[namelist:radiative_gases=nh3_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas NH3 +length=: +sort-key=Panel-A14f +type=integer + +[namelist:radiative_gases=nh3_mix_ratio] +compulsory=true +description=NH3 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A14b +type=real + +[namelist:radiative_gases=nh3_rad_opt] +compulsory=true +description=Radiative options for NH3 +!enumeration=true +help=RT options for the mixing ratio of NH3 +sort-key=Panel-A14a +trigger=namelist:radiative_gases=nh3_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=nh3_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=nh3_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=nh3_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=nh3_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=o2_clim_fcg_levls] +compulsory=true +description=List of values for growth for the O2 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A15c +type=real + +[namelist:radiative_gases=o2_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the O2 gas +sort-key=Panel-A15d +type=integer + +[namelist:radiative_gases=o2_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the O2 gas +length=: +sort-key=Panel-A15e +type=real + +[namelist:radiative_gases=o2_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas O2 +length=: +sort-key=Panel-A15f +type=integer + +[namelist:radiative_gases=o2_mix_ratio] +compulsory=true +description=O2 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A15b +type=real + +[namelist:radiative_gases=o2_rad_opt] +compulsory=true +description=Radiative options for O2 +!enumeration=true +help=RT options for the mixing ratio of O2 +sort-key=Panel-A15a +trigger=namelist:radiative_gases=o2_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=o2_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=o2_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=o2_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=o2_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=o3_clim_fcg_levls] +compulsory=true +description=List of values for growth for the O3 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A16c +type=real + +[namelist:radiative_gases=o3_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the O3 gas +sort-key=Panel-A16d +type=integer + +[namelist:radiative_gases=o3_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the O3 gas +length=: +sort-key=Panel-A16e +type=real + +[namelist:radiative_gases=o3_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas O3 +length=: +sort-key=Panel-A16f +type=integer + +[namelist:radiative_gases=o3_mix_ratio] +compulsory=true +description=O3 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A16b +type=real + +[namelist:radiative_gases=o3_profile_data] +!bounds=namelist:radiative_gases=o3_profile_size +compulsory=true +description=Initial ozone profile +help=Values specifying mixing ratio (kg/kg) of ozone at heights specified + =in profile_heights. +!kind=default +length=: +range=0.0: +sort-key=Panel-A16i +type=real + +[namelist:radiative_gases=o3_profile_heights] +!bounds=namelist:radiative_gases=o3_profile_size +compulsory=true +description=Nodal heights for ozone profile +help=Heights, in metres, of nodes for specifying an ozone profile +!kind=default +length=: +range=0.0: +sort-key=Panel-A16h +type=real + +[namelist:radiative_gases=o3_profile_size] +compulsory=true +description=Number of points in initial ozone profile +help=Number of data points in the initial profile +!kind=default +range=0:200 +sort-key=Panel-A16g +type=integer + +[namelist:radiative_gases=o3_rad_opt] +compulsory=true +description=Radiative options for O3 +!enumeration=true +help=RT options for the mixing ratio of O3 +sort-key=Panel-A16a +trigger=namelist:radiative_gases=o3_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=o3_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=o3_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=o3_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=o3_mix_ratio: 'constant'; + =namelist:radiative_gases=o3_profile_data: 'profile'; + =namelist:radiative_gases=o3_profile_heights: 'profile'; + =namelist:radiative_gases=o3_profile_size: 'profile'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =1D specified profile, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'profile', 'prognostic', 'ancil' + +[namelist:radiative_gases=rb_clim_fcg_levls] +compulsory=true +description=List of values for growth for the Rb gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A22c +type=real + +[namelist:radiative_gases=rb_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the Rb gas +sort-key=Panel-A22d +type=integer + +[namelist:radiative_gases=rb_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the Rb gas +length=: +sort-key=Panel-A22e +type=real + +[namelist:radiative_gases=rb_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas Rb +length=: +sort-key=Panel-A22f +type=integer + +[namelist:radiative_gases=rb_mix_ratio] +compulsory=true +description=Rb mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A22b +type=real + +[namelist:radiative_gases=rb_rad_opt] +compulsory=true +description=Radiative options for Rb +!enumeration=true +help=RT options for the mixing ratio of Rb +sort-key=Panel-A22a +trigger=namelist:radiative_gases=rb_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=rb_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=rb_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=rb_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=rb_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=so2_clim_fcg_levls] +compulsory=true +description=List of values for growth for the SO2 gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A17c +type=real + +[namelist:radiative_gases=so2_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the SO2 gas +sort-key=Panel-A17d +type=integer + +[namelist:radiative_gases=so2_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the SO2 gas +length=: +sort-key=Panel-A17e +type=real + +[namelist:radiative_gases=so2_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas SO2 +length=: +sort-key=Panel-A17f +type=integer + +[namelist:radiative_gases=so2_mix_ratio] +compulsory=true +description=SO2 mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A17b +type=real + +[namelist:radiative_gases=so2_rad_opt] +compulsory=true +description=Radiative options for SO2 +!enumeration=true +help=RT options for the mixing ratio of SO2 +sort-key=Panel-A17a +trigger=namelist:radiative_gases=so2_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=so2_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=so2_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=so2_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=so2_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=tio_clim_fcg_levls] +compulsory=true +description=List of values for growth for the TiO gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A23c +type=real + +[namelist:radiative_gases=tio_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the TiO gas +sort-key=Panel-A23d +type=integer + +[namelist:radiative_gases=tio_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the TiO gas +length=: +sort-key=Panel-A23e +type=real + +[namelist:radiative_gases=tio_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas TiO +length=: +sort-key=Panel-A23f +type=integer + +[namelist:radiative_gases=tio_mix_ratio] +compulsory=true +description=TiO mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A23b +type=real + +[namelist:radiative_gases=tio_rad_opt] +compulsory=true +description=Radiative options for TiO +!enumeration=true +help=RT options for the mixing ratio of TiO +sort-key=Panel-A23a +trigger=namelist:radiative_gases=tio_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=tio_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=tio_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=tio_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=tio_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' + +[namelist:radiative_gases=vo_clim_fcg_levls] +compulsory=true +description=List of values for growth for the VO gas +help=Mass mixing ratio at the beginning of each year. +length=: +sort-key=Panel-A24c +type=real + +[namelist:radiative_gases=vo_clim_fcg_nyears] +compulsory=true +description=N of years at which forcing rate is specified for the VO gas +sort-key=Panel-A24d +type=integer + +[namelist:radiative_gases=vo_clim_fcg_rates] +compulsory=true +description=List of rates of growth for the VO gas +length=: +sort-key=Panel-A24e +type=real + +[namelist:radiative_gases=vo_clim_fcg_years] +compulsory=true +description=List of years at which forcing rate or level is specified for + =radiatively the active gas VO +length=: +sort-key=Panel-A24f +type=integer + +[namelist:radiative_gases=vo_mix_ratio] +compulsory=true +description=VO mass mixing ratio +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A24b +type=real + +[namelist:radiative_gases=vo_rad_opt] +compulsory=true +description=Radiative options for VO +!enumeration=true +help=RT options for the mixing ratio of VO +sort-key=Panel-A24a +trigger=namelist:radiative_gases=vo_clim_fcg_levls: 'time_varying'; + =namelist:radiative_gases=vo_clim_fcg_nyears: 'time_varying'; + =namelist:radiative_gases=vo_clim_fcg_years: 'time_varying'; + =namelist:radiative_gases=vo_clim_fcg_rates: 'time_varying'; + =namelist:radiative_gases=vo_mix_ratio: 'constant'; +value-titles=Turned off i.e. transparent to radiation, + =Constant well mixed value, + =Time varying well mixed value, + =3D prognostic field, + =3D field from an ancillary file +values='off', 'constant', 'time_varying', 'prognostic', 'ancil' diff --git a/interfaces/socrates_interface/source/algorithm/cosp_alg_mod.x90 b/interfaces/socrates_interface/source/algorithm/cosp_alg_mod.x90 index 369cf04a5..adf6728a3 100644 --- a/interfaces/socrates_interface/source/algorithm/cosp_alg_mod.x90 +++ b/interfaces/socrates_interface/source/algorithm/cosp_alg_mod.x90 @@ -14,15 +14,15 @@ use fs_continuity_mod, only: W3, Wtheta use sci_geometric_constants_mod, & only: get_height_fv use integer_field_mod, only: integer_field_type -use io_config_mod, only: write_diag, use_xios_io, subroutine_timers +use io_config_mod, only: write_diag, use_xios_io use mesh_mod, only: mesh_type use mphys_inputs_mod, only: x1r, x2r use mphys_psd_mod, only: x1g, x2g, x4g use microphysics_config_mod, only: microphysics_casim use mr_indices_mod, only: nummr, imr_v, imr_cl, imr_s, imr_ci use planet_config_mod, only: p_zero, kappa -use timer_mod, only: timer -use log_mod, only: log_event, LOG_LEVEL_INFO +use timing_mod, only: start_timing, stop_timing, tik, LPROF +use log_mod, only: log_event, LOG_LEVEL_DEBUG use cosp_config_mod, only: n_subcol_gen use cosp_diags_mod, only: initialise_diags_for_cosp, output_diags_for_cosp @@ -89,10 +89,11 @@ subroutine cosp_alg(pressure_in_wth, temperature_in_wth, exner, mr, & type( field_type ) :: pressure_in_w3, mr_ice, n_ice real( r_def ) :: inv_kappa real( r_def ) :: cosp_x1r, cosp_x2r, cosp_x1g, cosp_x2g, cosp_x4g + integer( tik ) :: id ! Unpacked fields from collections type( field_type ), pointer :: rho_in_wth => null() - type( field_type ), pointer :: lit_fraction => null() + type( field_type ), pointer :: lit_fraction_cosp => null() type( field_type ), pointer :: liquid_fraction => null() type( field_type ), pointer :: frozen_fraction => null() type( field_type ), pointer :: sigma_ml @@ -122,12 +123,14 @@ subroutine cosp_alg(pressure_in_wth, temperature_in_wth, exner, mr, & cloud_thermal_absorptivity, cloud_solar_extinction - call log_event( 'slow_physics: Running COSP', LOG_LEVEL_INFO ) + call log_event( 'slow_physics: Running COSP', LOG_LEVEL_DEBUG ) + + if ( LPROF ) call start_timing( id, 'cosp' ) ! Unpack fields from collections call derived_fields%get_field('rho_in_wth', rho_in_wth) - call radiation_fields%get_field('lit_fraction', lit_fraction) + call radiation_fields%get_field('lit_fraction_cosp', lit_fraction_cosp) call cloud_fields%get_field('liquid_fraction', liquid_fraction) call cloud_fields%get_field('frozen_fraction', frozen_fraction) @@ -189,7 +192,6 @@ subroutine cosp_alg(pressure_in_wth, temperature_in_wth, exner, mr, & cloud_thermal_absorptivity, cloud_solar_extinction) ! Run COSP - if ( subroutine_timers ) call timer("cosp") call invoke( cosp_kernel_type( & pressure_in_wth, temperature_in_wth, rho_in_wth, height_wth, & pressure_in_w3, height_w3, & @@ -201,7 +203,7 @@ subroutine cosp_alg(pressure_in_wth, temperature_in_wth, exner, mr, & conv_liquid_mmr, conv_frozen_mmr, conv_frozen_number, & sigma_ml, sigma_mi, cloud_drop_no_conc, & ls_rain_3d, conv_rain_3d, conv_snow_3d, & - lit_fraction, rand_seed, n_cloud_layer, & + lit_fraction_cosp, rand_seed, n_cloud_layer, & n_subcol_gen, & cosp_x1r, cosp_x2r, cosp_x1g, cosp_x2g, cosp_x4g, & sunlit_mask, & @@ -216,7 +218,7 @@ subroutine cosp_alg(pressure_in_wth, temperature_in_wth, exner, mr, & calipso_total_backscatter, & calipso_cfad_sr_40_lvls, & cloud_thermal_absorptivity, cloud_solar_extinction ) ) - if ( subroutine_timers ) call timer("cosp") + if ( LPROF ) call stop_timing( id, 'cosp' ) ! Output diagnostics if (write_diag .and. use_xios_io) then diff --git a/interfaces/socrates_interface/source/algorithm/cosp_diags_mod.x90 b/interfaces/socrates_interface/source/algorithm/cosp_diags_mod.x90 index 59448ec4e..4dd83d588 100644 --- a/interfaces/socrates_interface/source/algorithm/cosp_diags_mod.x90 +++ b/interfaces/socrates_interface/source/algorithm/cosp_diags_mod.x90 @@ -10,9 +10,8 @@ module cosp_diags_mod use constants_mod, only: l_def use cosp_config_mod, only: l_cosp use field_mod, only: field_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_INFO - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field, & diagnostic_to_be_sampled @@ -144,8 +143,9 @@ subroutine initialise_diags_for_cosp( & calipso_cf_40_lvls_undet, & calipso_cf_40_lvls_mask, & cloud_thermal_absorptivity, cloud_solar_extinction + integer(tik) :: id - if ( subroutine_timers ) call timer("cosp_diags") + if ( LPROF ) call start_timing( id, 'diags.cosp' ) sunlit_mask_flag = init_diag( sunlit_mask, & 'cosp__sunlit_mask' ) @@ -180,7 +180,7 @@ subroutine initialise_diags_for_cosp( & cloud_solar_extinction_flag = init_diag( cloud_solar_extinction, & 'cosp__cloud_solar_extinction' ) - if ( subroutine_timers ) call timer("cosp_diags") + if ( LPROF ) call stop_timing( id, 'diags.cosp' ) end subroutine initialise_diags_for_cosp @@ -231,8 +231,9 @@ subroutine output_diags_for_cosp( & calipso_cf_40_lvls_undet, & calipso_cf_40_lvls_mask, & cloud_thermal_absorptivity, cloud_solar_extinction + integer(tik) :: id - if ( subroutine_timers ) call timer("cosp_diags") + if ( LPROF ) call start_timing( id, 'diags.cosp' ) ! Diagnostics computed within the kernels if (sunlit_mask_flag) call & @@ -284,7 +285,7 @@ subroutine output_diags_for_cosp( & cloud_solar_extinction%write_field( & cloud_solar_extinction%get_name() ) - if ( subroutine_timers ) call timer("cosp_diags") + if ( LPROF ) call stop_timing( id, 'diags.cosp' ) end subroutine output_diags_for_cosp end module cosp_diags_mod diff --git a/interfaces/socrates_interface/source/algorithm/illuminate_alg_mod.x90 b/interfaces/socrates_interface/source/algorithm/illuminate_alg_mod.x90 index f7f2dce8c..69c02b4d1 100644 --- a/interfaces/socrates_interface/source/algorithm/illuminate_alg_mod.x90 +++ b/interfaces/socrates_interface/source/algorithm/illuminate_alg_mod.x90 @@ -16,9 +16,7 @@ use io_config_mod, only: write_diag, use_xios_io use sci_geometric_constants_mod, & only: get_latitude_fv, get_longitude_fv use illuminate_kernel_mod, only: illuminate_kernel_type -use io_config_mod, only: subroutine_timers -use timer_mod, only: timer - +use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none private @@ -53,6 +51,7 @@ subroutine illuminate_alg(radiation_fields, timestep, dt) type( field_type ), pointer :: lit_fraction => null() type( field_type ), pointer :: cos_zenith_angle_rts => null() type( field_type ), pointer :: lit_fraction_rts => null() + type( field_type ), pointer :: lit_fraction_cosp => null() type( field_type ), pointer :: stellar_irradiance_rts => null() type( field_type ), pointer :: sin_stellar_declination_rts => null() type( field_type ), pointer :: stellar_eqn_of_time_rts => null() @@ -63,19 +62,21 @@ subroutine illuminate_alg(radiation_fields, timestep, dt) type( field_type ), pointer :: horizon_aspect => null() type( field_type ), pointer :: skyview => null() - type(xios_date) :: datetime + type(xios_date) :: datetime integer(i_def), save :: current_year, day_of_year - real(r_def), save :: second_of_day + real(r_def), save :: second_of_day logical(l_def), save :: first_call = .true. + integer(tik) :: id_alg, id_diags if (.not. first_call) then - if ( subroutine_timers ) call timer("illuminate_alg") + if ( LPROF ) call start_timing( id_alg, 'radiation.illuminate' ) call radiation_fields%get_field('cos_zenith_angle',cos_zenith_angle) call radiation_fields%get_field('lit_fraction',lit_fraction) call radiation_fields%get_field('cos_zenith_angle_rts',cos_zenith_angle_rts) call radiation_fields%get_field('lit_fraction_rts',lit_fraction_rts) + call radiation_fields%get_field('lit_fraction_cosp',lit_fraction_cosp) call radiation_fields%get_field('stellar_irradiance_rts', & stellar_irradiance_rts) call radiation_fields%get_field('sin_stellar_declination_rts', & @@ -98,6 +99,7 @@ subroutine illuminate_alg(radiation_fields, timestep, dt) call invoke( illuminate_kernel_type( & cos_zenith_angle, lit_fraction, & cos_zenith_angle_rts, lit_fraction_rts, & + lit_fraction_cosp, & stellar_irradiance_rts, & sin_stellar_declination_rts, & stellar_eqn_of_time_rts, & @@ -107,11 +109,11 @@ subroutine illuminate_alg(radiation_fields, timestep, dt) latitude, longitude, timestep, dt, & current_year, day_of_year, second_of_day) ) - if ( subroutine_timers ) call timer("illuminate_alg") + if ( LPROF ) call stop_timing( id_alg, 'radiation.illuminate' ) ! Output diagnostics if (write_diag .and. use_xios_io) then - if ( subroutine_timers ) call timer("illuminate_xios") + if ( LPROF ) call start_timing( id_diags, 'diags.illuminate' ) call sin_stellar_declination_rts%write_field(& 'radiation__sin_stellar_declination_rts') @@ -123,7 +125,7 @@ subroutine illuminate_alg(radiation_fields, timestep, dt) call horizon_aspect%write_field('radiation__horizon_aspect') call skyview%write_field('radiation__skyview') - if ( subroutine_timers ) call timer("illuminate_xios") + if ( LPROF ) call stop_timing( id_diags, 'diags.illuminate' ) end if nullify( mesh ) diff --git a/interfaces/socrates_interface/source/algorithm/radiation_alg_mod.x90 b/interfaces/socrates_interface/source/algorithm/radiation_alg_mod.x90 index 3678847f0..7d990d067 100644 --- a/interfaces/socrates_interface/source/algorithm/radiation_alg_mod.x90 +++ b/interfaces/socrates_interface/source/algorithm/radiation_alg_mod.x90 @@ -25,8 +25,7 @@ use sw_mts_kernel_mod, only: sw_mts_kernel_type use lw_kernel_mod, only: lw_kernel_type use lw_inc_kernel_mod, only: lw_inc_kernel_type use lw_mts_kernel_mod, only: lw_mts_kernel_type -use io_config_mod, only: subroutine_timers -use timer_mod, only: timer +use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_DEBUG, LOG_LEVEL_INFO use log_field_alg_mod, only: log_field_alg use lfric_xios_write_mod, only: write_field_generic @@ -278,6 +277,7 @@ subroutine radiation_alg(dtheta_rad, theta, exner, mr, moist_dyn, & sw_direct_uv_surf_rts, sw_direct_uv_clear_surf_rts, & sw_up_uv_surf_rts, sw_up_uv_clear_surf_rts, & photolysis_rates_rts + integer( tik ) :: id_sw, id_lw call log_event( 'slow_physics: Running Radiation', LOG_LEVEL_DEBUG ) @@ -498,8 +498,7 @@ subroutine radiation_alg(dtheta_rad, theta, exner, mr, moist_dyn, & end if - if ( subroutine_timers ) call timer("sw_radiation") - + if ( LPROF ) call start_timing( id_sw, 'radiation.sw' ) if (rad_this_tstep) then ! -------------------------------------------------- ! Radiation time-step: full calculation of SW fluxes @@ -603,8 +602,8 @@ subroutine radiation_alg(dtheta_rad, theta, exner, mr, moist_dyn, & call log_field_alg( sw_up_tile, LOG_LEVEL_DEBUG ) call log_field_alg( sw_up_blue_tile, LOG_LEVEL_DEBUG ) - if ( subroutine_timers ) call timer("sw_radiation") - if ( subroutine_timers ) call timer("lw_radiation") + if ( LPROF ) call stop_timing( id_sw, 'radiation.sw' ) + if ( LPROF ) call start_timing( id_lw, 'radiation.lw' ) if (rad_this_tstep) then ! -------------------------------------------------- @@ -686,7 +685,7 @@ subroutine radiation_alg(dtheta_rad, theta, exner, mr, moist_dyn, & call log_field_alg( lw_down_surf, LOG_LEVEL_DEBUG ) call log_field_alg( lw_up_tile, LOG_LEVEL_DEBUG ) - if ( subroutine_timers ) call timer("lw_radiation") + if ( LPROF ) call stop_timing( id_lw, 'radiation.lw' ) ! first calculate the total temperature increment dt_again=dt diff --git a/interfaces/socrates_interface/source/algorithm/radiation_diags_mod.x90 b/interfaces/socrates_interface/source/algorithm/radiation_diags_mod.x90 index 17b189e9f..9f4bf512d 100644 --- a/interfaces/socrates_interface/source/algorithm/radiation_diags_mod.x90 +++ b/interfaces/socrates_interface/source/algorithm/radiation_diags_mod.x90 @@ -10,8 +10,7 @@ module radiation_diags_mod use constants_mod, only: i_def, l_def, r_def use field_mod, only: field_type use integer_field_mod, only: integer_field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field, & diagnostic_to_be_sampled @@ -172,8 +171,9 @@ subroutine initialise_diags_for_radiation( lw_down_surf, lw_heating_rate, & ! Local working variables logical( l_def ) :: ignore + integer( tik ) :: id - if ( subroutine_timers ) call timer("radiation_diags") + if ( LPROF ) call start_timing( id, 'diags.radiation' ) ! Diagnostic fields that are always required by the kernels lw_up_surf_flag = init_diag( lw_up_surf, & @@ -355,7 +355,7 @@ subroutine initialise_diags_for_radiation( lw_down_surf, lw_heating_rate, & ignore = init_diag( warm_cloud_top_re_rts, & 'radiation__warm_cloud_top_re_rts', activate=.true. ) - if ( subroutine_timers ) call timer("radiation_diags") + if ( LPROF ) call stop_timing( id, 'diags.radiation' ) end subroutine initialise_diags_for_radiation @@ -496,8 +496,9 @@ subroutine output_diags_for_radiation( dtheta_rad, & ! Local working variables logical( l_def ) :: ignore + integer( tik ) :: id - if ( subroutine_timers ) call timer("radiation_diags") + if ( LPROF ) call start_timing( id, 'diags.radiation' ) ! Prognostic fields call dtheta_rad%write_field('radiation__dtheta_rad') @@ -743,7 +744,7 @@ subroutine output_diags_for_radiation( dtheta_rad, & if ( photolysis_rates_rts_flag ) call photolysis_rates_rts%write_field() - if ( subroutine_timers ) call timer("radiation_diags") + if ( LPROF ) call stop_timing( id, 'diags.radiation' ) end subroutine output_diags_for_radiation end module radiation_diags_mod diff --git a/interfaces/socrates_interface/source/kernel/illuminate_kernel_mod.F90 b/interfaces/socrates_interface/source/kernel/illuminate_kernel_mod.F90 index e4f1a23a4..0ac2f4566 100644 --- a/interfaces/socrates_interface/source/kernel/illuminate_kernel_mod.F90 +++ b/interfaces/socrates_interface/source/kernel/illuminate_kernel_mod.F90 @@ -29,11 +29,12 @@ module illuminate_kernel_mod ! Contains the metadata needed by the PSy layer. type, public, extends(kernel_type) :: illuminate_kernel_type private - type(arg_type) :: meta_args(19) = (/ & + type(arg_type) :: meta_args(20) = (/ & arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! cos_zenith_angle arg_type(GH_FIELD, GH_REAL, GH_WRITE, ANY_DISCONTINUOUS_SPACE_1), & ! lit_fraction arg_type(GH_FIELD, GH_REAL, GH_READWRITE, ANY_DISCONTINUOUS_SPACE_1), & ! cos_zenith_angle_rts arg_type(GH_FIELD, GH_REAL, GH_READWRITE, ANY_DISCONTINUOUS_SPACE_1), & ! lit_fraction_rts + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, ANY_DISCONTINUOUS_SPACE_1), & ! lit_fraction_cosp arg_type(GH_FIELD, GH_REAL, GH_READWRITE, ANY_DISCONTINUOUS_SPACE_1), & ! stellar_irradiance_rts arg_type(GH_FIELD, GH_REAL, GH_READWRITE, ANY_DISCONTINUOUS_SPACE_1), & ! sin_stellar_declination_rts arg_type(GH_FIELD, GH_REAL, GH_READWRITE, ANY_DISCONTINUOUS_SPACE_1), & ! stellar_eqn_of_time_rts @@ -66,7 +67,8 @@ module illuminate_kernel_mod !> @param[in,out] cos_zenith_angle Cosine of the stellar zenith angle !> @param[in,out] lit_fraction Lit fraction of the timestep !> @param[in,out] cos_zenith_angle_rts Cosine of the stellar zenith angle -!> @param[in,out] lit_fraction_rts Lit fraction of the timestep +!> @param[in,out] lit_fraction_rts Lit fraction of the radiation timestep +!> @param[in,out] lit_fraction_cosp Lit fraction of the COSP timestep !> @param[in,out] stellar_irradiance_rts Stellar irradiance at the planet !> @param[in,out] sin_stellar_declination_rts Stellar declination !> @param[in,out] stellar_eqn_of_time_rts Stellar equation of time @@ -96,6 +98,7 @@ subroutine illuminate_code(nlayers, & lit_fraction, & cos_zenith_angle_rts, & lit_fraction_rts, & + lit_fraction_cosp, & stellar_irradiance_rts, & sin_stellar_declination_rts, & stellar_eqn_of_time_rts, & @@ -113,6 +116,7 @@ subroutine illuminate_code(nlayers, & use radiation_config_mod, only: n_radstep, n_horiz_ang, n_horiz_layer, & topography, & topography_slope, topography_horizon + use cosp_config_mod, only: l_cosp, n_cosp_step use star_config_mod, only: stellar_constant use orbit_config_mod, only: & elements, elements_user, elements_earth_fixed, & @@ -141,9 +145,10 @@ subroutine illuminate_code(nlayers, & integer(i_def), intent(in) :: map_h_asp(ndf_h_asp) real(r_def), dimension(undf_2d), intent(inout):: & - cos_zenith_angle, lit_fraction - real(r_def), dimension(undf_2d), intent(inout):: & - cos_zenith_angle_rts, lit_fraction_rts, stellar_irradiance_rts, & + cos_zenith_angle, lit_fraction, & + cos_zenith_angle_rts, lit_fraction_rts, & + lit_fraction_cosp, & + stellar_irradiance_rts, & sin_stellar_declination_rts, stellar_eqn_of_time_rts, & orographic_correction_rts real(r_def), dimension(undf_2d), intent(in) :: slope_angle, slope_aspect @@ -158,7 +163,7 @@ subroutine illuminate_code(nlayers, & integer :: h_ang_1, h_ang_last integer :: h_asp_1, h_asp_last logical :: l_slope, l_shading - + real(r_def), dimension(undf_2d) :: cos_zenith_angle_cosp ! Set orbital elements select case (elements) @@ -282,6 +287,34 @@ subroutine illuminate_code(nlayers, & lit_fraction = lit_fraction(map_2d(1):map_2d(1)) ) end if + if (l_cosp) then + if (n_cosp_step == 1) then + lit_fraction_cosp(map_2d(1):map_2d(1)) & + = lit_fraction(map_2d(1):map_2d(1)) + else if (n_cosp_step == n_radstep) then + lit_fraction_cosp(map_2d(1):map_2d(1)) & + = lit_fraction_rts(map_2d(1):map_2d(1)) + else if (mod(timestep-1_i_def, n_cosp_step) == 0) then + ! Calculate parameters for external illumination of the atmosphere + ! over the COSP timestep + call illuminate( & + l_stellar_angle = .true., & + n_profile = n_profile, & + i_spin = i_spin, & + second_of_day = second_of_day, & + length_of_timestep = dt*real(n_cosp_step, r_def), & + hour_angle_inc = hour_angle_inc, & + fixed_zenith_angle = fixed_zenith_angle, & + fixed_azimuth_angle = fixed_azimuth_angle, & + latitude = latitude(map_2d(1):map_2d(1)), & + longitude = longitude(map_2d(1):map_2d(1)), & + sin_stellar_declination = sin_stellar_declination_rts(map_2d(1)), & + stellar_eqn_of_time = stellar_eqn_of_time_rts(map_2d(1)), & + cos_zenith_angle = cos_zenith_angle_cosp(map_2d(1):map_2d(1)), & + lit_fraction = lit_fraction_cosp(map_2d(1):map_2d(1)) ) + end if + end if + end subroutine illuminate_code end module illuminate_kernel_mod diff --git a/rose-stem/app/adjoint_tests/file/field_def_diags_ls.xml b/rose-stem/app/adjoint_tests/file/field_def_diags_ls.xml new file mode 100644 index 000000000..8a2c34e54 --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/field_def_diags_ls.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/file_def_ancil.xml b/rose-stem/app/adjoint_tests/file/file_def_ancil.xml new file mode 100644 index 000000000..43c9e9e44 --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/file_def_ancil.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/file_def_check_restart.xml b/rose-stem/app/adjoint_tests/file/file_def_check_restart.xml new file mode 100644 index 000000000..05ba6dcbc --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/file_def_check_restart.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/file_def_diags.xml b/rose-stem/app/adjoint_tests/file/file_def_diags.xml new file mode 100644 index 000000000..c12613f00 --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/file_def_diags.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/file_def_diags_ls.xml b/rose-stem/app/adjoint_tests/file/file_def_diags_ls.xml new file mode 100644 index 000000000..0cdd03798 --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/file_def_diags_ls.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/file_def_initial.xml b/rose-stem/app/adjoint_tests/file/file_def_initial.xml new file mode 100644 index 000000000..05a68968e --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/file_def_initial.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/file_def_ls.xml b/rose-stem/app/adjoint_tests/file/file_def_ls.xml new file mode 100644 index 000000000..a2766a236 --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/file_def_ls.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/file_def_read.xml b/rose-stem/app/adjoint_tests/file/file_def_read.xml new file mode 100644 index 000000000..61cc7f81e --- /dev/null +++ b/rose-stem/app/adjoint_tests/file/file_def_read.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/adjoint_tests/file/iodef.xml b/rose-stem/app/adjoint_tests/file/iodef.xml index ab5722770..fb000671f 100644 --- a/rose-stem/app/adjoint_tests/file/iodef.xml +++ b/rose-stem/app/adjoint_tests/file/iodef.xml @@ -5,285 +5,59 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -291,7 +65,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/adjoint_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 000000000..125a4758d --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-default.conf b/rose-stem/app/adjoint_tests/opt/rose-app-default.conf index e69de29bb..dba827637 100644 --- a/rose-stem/app/adjoint_tests/opt/rose-app-default.conf +++ b/rose-stem/app/adjoint_tests/opt/rose-app-default.conf @@ -0,0 +1,3 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/adjoint_tests/file/iodef.xml diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 000000000..864c6a623 --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,20 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/linear_model/file/iodef.xml + +[namelist:files] +ls_directory='$BIG_DATA_DIR/tangent-linear/PullRequest182' +ls_filename='final_ls_with_land' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +start_dump_filename='final_pert' + +[namelist:io] +diagnostic_frequency=8 + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2016-01-01 15:00:00' +calendar_start='2016-01-01 15:00:00' diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-rrt_equals_dt.conf b/rose-stem/app/adjoint_tests/opt/rose-app-rrt_equals_dt.conf new file mode 100644 index 000000000..3d9745645 --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-rrt_equals_dt.conf @@ -0,0 +1,2 @@ +[namelist:mixed_solver] +reference_reset_time=$DT diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-strict_solver.conf b/rose-stem/app/adjoint_tests/opt/rose-app-strict_solver.conf new file mode 100644 index 000000000..77270e0f5 --- /dev/null +++ b/rose-stem/app/adjoint_tests/opt/rose-app-strict_solver.conf @@ -0,0 +1,15 @@ +[namelist:helmholtz_solver] +gcrk=18 +si_pressure_a_tol=0 +si_pressure_tolerance=1.0e-15 + +[namelist:mixed_solver] +fail_on_non_converged=.false. +gcrk=10 +mixed_solver_a_tol=1.0e-21 +si_maximum_iterations=100 +si_tolerance=1.0e-21 + +[namelist:solver] +maximum_iterations=50 +tolerance=1.0e-18 diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf b/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf index cada49b40..81be83085 100644 --- a/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf +++ b/rose-stem/app/adjoint_tests/opt/rose-app-suite_controlled.conf @@ -18,7 +18,7 @@ checkpoint_read=${RESTART_READ} checkpoint_times= checkpoint_write=${RESTART_WRITE} end_of_run_checkpoint=.true. -!!nodal_output_on_w3=${NODAL_OUTPUT_ON_W3} +nodal_output_on_w3=${NODAL_OUTPUT_ON_W3} use_xios_io=${USE_XIOS_IO} [namelist:logging] diff --git a/rose-stem/app/adjoint_tests/opt/rose-app-varying_ls.conf b/rose-stem/app/adjoint_tests/opt/rose-app-varying_ls.conf index 6ff994e7f..dddbeae1e 100644 --- a/rose-stem/app/adjoint_tests/opt/rose-app-varying_ls.conf +++ b/rose-stem/app/adjoint_tests/opt/rose-app-varying_ls.conf @@ -1,2 +1,3 @@ [namelist:linear] fixed_ls=.false. +transport_efficiency=.false. diff --git a/rose-stem/app/adjoint_tests/rose-app.conf b/rose-stem/app/adjoint_tests/rose-app.conf index 76c5b0144..4dafac183 100644 --- a/rose-stem/app/adjoint_tests/rose-app.conf +++ b/rose-stem/app/adjoint_tests/rose-app.conf @@ -1,11 +1,11 @@ -meta=lfric-adjoint_tests/vn3.0 +meta=lfric-adjoint_tests/vn3.0_t108 [command] -default=$LAUNCH_SCRIPT/launch-exe +default=rose env-cat iodef_temp.xml -o iodef.xml; $LAUNCH_SCRIPT/launch-exe [env] ENSEMBLE_MEMBER=0 -EXEC_NAME=adjoint_test +EXEC_NAME=adjoint_tests OMP_NUM_THREADS=1 TOTAL_RANKS=1 XIOS_SERVER_MODE=True @@ -16,13 +16,19 @@ mode=mkdir [file:configuration.nml] mode=auto -source=namelist:base_mesh +source=(namelist:aerosol) + = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -33,6 +39,7 @@ source=namelist:base_mesh = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -43,26 +50,45 @@ source=namelist:base_mesh = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) + = (namelist:jules_nvegparm) + = (namelist:jules_pftparm) + = (namelist:jules_radiation) + = (namelist:jules_sea_seaice) + = (namelist:jules_soil) + = (namelist:jules_snow) + = (namelist:jules_surface) + = (namelist:jules_surface_types) + = (namelist:jules_urban) + = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver + = (namelist:specified_surface) + = (namelist:star) + = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) = namelist:time @@ -84,25 +110,25 @@ source=namelist:base_mesh easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. -!!emissions='GC3' -glomap_mode='off' +!!emissions='GC5' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. -!!murk_source_scaling=0 +!!murk_source_scaling=1.0 !!murk_visibility=.false. -!!n_radaer_step=0 -!!prec_file='' -sulphuric_strat_climatology=.false. -!!sulphuric_strat_column=0 +!!n_radaer_step=1 +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. +!!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -110,65 +136,66 @@ prime_mesh_name='dynamics' topology='fully_periodic' [!!namelist:blayer] -a_ent_2=0 -a_ent_shr=0 +a_ent_2=0.056 +a_ent_shr=1.6 +bl_levels=50 bl_mix_w=.false. bl_res_inv='cosine_inv_flux' c_gust=4.0 -!!cbl_mix_fac=0 +!!cbl_mix_fac=0.0 cbl_opt='conventional' -dec_thres_cloud=0 +dec_thres_cloud=0.1 dec_thres_cu=0.05 -dyn_diag='zi_l_sea' +dyn_diag='zi_l_cu' dzrad_disc_opt='level_ntm1' entr_smooth_dec='on' flux_bc_opt='interactive' free_atm_mix='to_sharp' -fric_heating=.false. -interp_local='gradients' +fric_heating=.true. +interp_local='cf_dbdz' kprof_cu='buoy_integ' l_converge_ga=.false. l_use_sml_dsc_fixes=.false. -near_neut_z_on_l=0 -new_kcloudtop=.false. +near_neut_z_on_l=1.6 +new_kcloudtop=.true. ng_stress='BG97_limited' noice_in_turb=.false. num_sweeps_bflux=3 -p_unstable=0 -reduce_fa_mix='inv_and_cu_lcl' -sbl_opt='sharpest' +p_unstable=1.0 +reduce_fa_mix='inv_only' +sbl_opt='sharp_sea_mes_land' sc_diag_opt='orig' sg_orog_mixing='none' -!!zhloc_depth_fac=0 +!!zhloc_depth_fac=0.4 [namelist:boundaries] -!!blend_frequency='inner' -!!blending_weights=0 -!!blending_weights_w2v=0 -!!boundary_e=0 -!!boundary_n=0 -!!boundary_s=0 -!!boundary_w=0 -!!edge_cells_ew=0 -!!edge_cells_ns=0 -!!inner_width_ew=0 -!!inner_width_ns=0 -!!lbc_eos_height=0 -!!lbc_method='onion_layer' +!!blend_frequency='final' +!!blending_weights=0.0 +!!blending_weights_w2v=0.0 +!!boundary_e=1 +!!boundary_n=1 +!!boundary_s=1 +!!boundary_w=1 +!!edge_cells_ew=1 +!!edge_cells_ns=1 +!!inner_width_ew=1 +!!inner_width_ns=1 +!!lbc_eos_height=100 +!!lbc_method='coordinate_based' limited_area=.false. -!!normal_only=.false. -!!outer_width_ew=0 -!!outer_width_ns=0 +!!normal_only=.true. +!!outer_width_ew=1 +!!outer_width_ns=1 !!output_lbcs=.false. -!!rim_width_ew=0 -!!rim_width_ns=0 -!!solver_boundary_depth=0 -!!transport_boundary_depth=0 -transport_overwrite_freq='split_step' +!!rim_width_ew=1 +!!rim_width_ns=1 +!!solver_boundary_depth=1 +!!transport_boundary_depth=6 +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. -!!max_cfl=0 +!!max_cfl=0.75 [!!namelist:chemistry] chem_scheme='none' @@ -184,58 +211,58 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] -!!cff_spread_rate=0 -cld_fsd_hill=.false. +!!cff_spread_rate=1.0e-5 +cld_fsd_hill=.true. cloud_call_b4_conv=.false. !!cloud_horizontal_ice_fsd=0.0 -!!cloud_horizontal_liq_fsd=0 +!!cloud_horizontal_liq_fsd=0.75 cloud_pc2_tol=0.005 cloud_pc2_tol_2=0.001 !!dbsdtbs_turb_0=1.5E-4 !!ent_coef_bm=0.2 -!!ez_max=0 -falliceshear_method='constant' -filter_optical_depth=.false. +!!ez_max=400.0 +falliceshear_method='real' +filter_optical_depth=.true. !!fsd_conv_const=2.81 !!fsd_min_conv_frac=0.0 !!fsd_nonconv_ice_const=1.14 !!fsd_nonconv_liq_const=1.14 -!!i_bm_ez_opt='orig' +!!i_bm_ez_opt='subcrit' !!i_pc2_erosion_numerics='implicit' -!!ice_width=0 +!!ice_width=0.02 !!l_bm_sigma_s_grad=.false. !!l_bm_tweaks=.false. !!max_sigmas=3.0 !!min_sigx_ft=0.0 !!mphys_erosion=.false. -!!opt_depth_thresh=0 +!!opt_depth_thresh=0.01 pc2_init_logic='original' -pc2ini='smith' -rh_crit=0 -rh_crit_opt='namelist' -scheme='smith' -subgrid_qv=.false. +pc2ini='bimodal' +rh_crit=0.920,0.918,0.916,0.912,0.908,0.903,64*0.9 +rh_crit_opt='tke' +scheme='pc2' +subgrid_qv=.true. !!turb_var_fac_bm=1.0 -two_d_fsd_factor=0 -use_fsd_eff_res=.false. +two_d_fsd_factor=1.65 +use_fsd_eff_res=.true. [namelist:convection] -!!cape_timescale=0 +!!cape_timescale=1800.0 !!cv_scheme='gregory_rowntree' dx_ref=50000.0 !!efrac=1.0 l_cvdiag_ctop_qmax=.false. -!!number_of_convection_substeps=0 +!!number_of_convection_substeps=2 !!orig_mdet_fac=1.0 !!par_gen_mass_fac=0.25 !!par_gen_rhpert=0.05 @@ -246,10 +273,11 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. -!!n_subcol_gen=0 +!!n_cosp_step=1 +!!n_subcol_gen=64 [namelist:damping_layer] -dl_base=10000.0 +dl_base=40000.0 dl_str=0.05 dl_type='standard' @@ -265,15 +293,15 @@ vertical_sorting=.false. [namelist:energy_correction] encorr_usage='none' integral_method='fd' -!!reset_hours=0 +!!reset_hours=24 [namelist:esm_couple] l_esm_couple_test=.false. [!!namelist:external_forcing] -!!diffusion_coefficient=0 -!!diffusion_order=0 -!!filtering_order=0 +!!diffusion_coefficient=0.05 +!!diffusion_order=1 +!!filtering_order=1 geostrophic_forcing=.false. !!hs_random=.false. !!pc2_force_response=.false. @@ -284,12 +312,13 @@ vertadvect_forcing=.false. wind_forcing='none' [namelist:extrusion] -domain_height=10000.0 +domain_height=80000.0 !!eta_values='' -method='uniform' -number_of_layers=5 +method='um_L70_50t_20s_80km' +number_of_layers=70 planet_radius=6371229.0 -stretching_method='linear' +stretching_height=17507.0 +stretching_method='smooth' [namelist:files] !!aerosols_ancil_path='' @@ -299,7 +328,7 @@ ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' checkpoint_stem_name='' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' -!!diag_stem_name='diagGungho' +diag_stem_name='diagGungho' !!dms_conc_ocean_ancil_path='' !!ea_ancil_directory='' !!easy_absorption_lw_ancil_path='' @@ -350,8 +379,8 @@ checkpoint_stem_name='' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -!!ls_directory='' -!!ls_filename='' +ls_directory='$BIG_DATA_DIR/tangent-linear/PullRequest182' +ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' @@ -366,8 +395,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='' -start_dump_filename='' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +start_dump_filename='final_2021060200-2021060207.pert' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -388,7 +417,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -398,7 +427,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -412,16 +441,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 -!!jacobi_relaxation=0 -method='bicgstab' -monitor_convergence=.true. +!!fail_on_non_converged=.false. +gcrk=8 +!!jacobi_relaxation=0.5 +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 si_pressure_maximum_iterations=400 -si_pressure_tolerance=1.0e-15 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -431,7 +460,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -460,71 +489,71 @@ si_pressure_tolerance=1.0e-15 !!start_time=0 [namelist:ideal_surface] -canopy_height=0 -leaf_area_index=0 -n_snow_layers=0 -snow_depth=0 -snow_layer_ice_mass=0 -snow_layer_temp=0 -snow_layer_thickness=0 -soil_moisture=0 -soil_temperature=0 -surf_tile_fracs=0 -surf_tile_temps=0 -tile_snow_mass=0 +canopy_height=19.01,16.38,0.79,1.26,1.0 +leaf_area_index=5.0,4.0,1.5,1.5,1.5 +n_snow_layers=11*0 +snow_depth=11*0.0 +snow_layer_ice_mass=27*0.0 +snow_layer_temp=27*273.0 +snow_layer_thickness=27*0.0 +soil_moisture=15.86,98.861,274.35,862.27 +soil_temperature=284.508,286.537,289.512,293.066 +surf_tile_fracs=9*0.0,1.0,0.0 +surf_tile_temps=9*295.0,300.0,265.0 +tile_snow_mass=11*0.0 [namelist:idealised] -f_lon_deg=0 +f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 z2=0.0 [namelist:initial_pressure] -method='sampled' +method='balanced' surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=0 -!!profile_heights=0 -!!profile_size=0 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0 -!!profile_heights=0 -!!profile_size=0 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='sbr_with_vertical' -!!profile_data_u=0 -!!profile_data_v=0 -!!profile_data_w=0 -!!profile_heights_uv=0 -!!profile_heights_w=0 -!!profile_size_uv=0 -!!profile_size_w=0 +profile='constant_uv' +!!profile_data_u=0.0 +!!profile_data_v=0.0 +!!profile_data_w=0.0 +!!profile_heights_uv=0.0 +!!profile_heights_w=0.0 +!!profile_size_uv=1 +!!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -533,12 +562,12 @@ ancil_option='none' coarse_aerosol_ancil=.false. coarse_orography_ancil=.false. coarse_ozone_ancil=.false. -init_option='analytic' +init_option='fd_start_dump' lbc_option='none' -ls_option='analytic' -!!model_eos_height=100 +ls_option='file' +model_eos_height=100 n_orog_smooth=0 -read_w2h_wind=.false. +read_w2h_wind=.true. sea_ice_source='ancillary' snow_source='start_dump' !!sst_source='ancillary' @@ -552,7 +581,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -!!diagnostic_frequency=1 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -562,113 +591,147 @@ subroutine_timers=.true. timer_output_path='timer.txt' use_xios_io=.true. write_conservation_diag=.false. -write_diag=.false. +write_diag=.true. write_dump=.false. write_fluxes=.false. -!!write_minmax_tseries=.false. +write_minmax_tseries=.false. [!!namelist:jules_hydrology] -l_hydrology=.false. -!!l_var_rainfrac=.false. +l_hydrology=.true. +!!l_var_rainfrac=.true. + +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' [!!namelist:jules_nvegparm] -albsnc_nvg_io=0 -albsnf_nvg_io=0 -!!albsnf_nvgl_io=0 -!!albsnf_nvgu_io=0 -catch_nvg_io=0 -ch_nvg_io=0 -emis_nvg_io=0 -gs_nvg_io=0 -infil_nvg_io=0 -vf_nvg_io=0 -z0_nvg_io=0 -z0hm_nvg_io=0 +albsnc_nvg_io=0.4,0.8,0.8,0.8 +albsnf_nvg_io=0.18,0.12,-1.0,0.75 +!!albsnf_nvgl_io=0.05,0.06,0.03,0.75 +!!albsnf_nvgu_io=0.20,0.15,0.80,0.75 +catch_nvg_io=0.5,0.0,0.0,0.0 +ch_nvg_io=2.8e5,2.11e7,0.0,0.0 +emis_nvg_io=0.970,0.985,0.900,0.990 +gs_nvg_io=0.0,0.0,1.0e-2,1.0e+6 +infil_nvg_io=0.1,0.0,0.5,0.0 +vf_nvg_io=1.0,1.0,0.0,0.0 +z0_nvg_io=1.0,1.0e-4,1.0e-3,5.0e-4 +z0hm_nvg_io=1.0e-7,2.5e-1,2.0e-1,2.0e-1 [!!namelist:jules_pftparm] -albsnc_max_io=0 -alnir_io=0 -alpar_io=0 +albsnc_max_io=2.5e-1,2.5e-1,6.0e-1,6.0e-1,4.0e-1 +alnir_io=0.341,0.272,0.369,0.368,0.395 +alpar_io=0.057,0.041,0.071,0.083,0.074 catch0_io=5*0.5 dcatch_dlai_io=5*0.05 -fsmc_p0_io=0 -kext_io=0 -knl_io=0 -omega_io=0 -omnir_io=0 -z0hm_pft_io=0 -!!z0v_io=0 +fsmc_p0_io=5*0.6 +kext_io=0.5,0.5,1.0,1.0,0.5 +knl_io=5*0.2 +omega_io=0.101,0.083,0.132,0.135,0.115 +omnir_io=0.788,0.545,0.864,0.787,0.785 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 +!!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] -!!fixed_sea_albedo=0 -i_sea_alb_method='barker' +!!fixed_sea_albedo=0.06 +i_sea_alb_method='jin' l_albedo_obs=.false. -l_hapke_soil=.false. -!!l_niso_direct=.false. -l_partition_albsoil=.false. -!!l_sea_alb_var_chl=.false. +l_hapke_soil=.true. +!!l_niso_direct=.true. +l_partition_albsoil=.true. +!!l_sea_alb_var_chl=.true. l_spec_alb_bs=.false. -!!ratio_albsoil=0 -!!swdn_frac_albsoil=0 +!!ratio_albsoil=2.0 +!!swdn_frac_albsoil=0.5 [!!namelist:jules_sea_seaice] -alpham=0 +alpham=0.72 amip_ice_thick=.false. -beta_evap=0 -buddy_sea='Off' -!!cdn_hw_sea=0 -!!cdn_max_sea=0 -dtice=0 -emis_sea=0 -emis_sice=0 -i_high_wind_drag='null' -iseasurfalg='specified_roughness' -l_10m_neut=.false. -l_iceformdrag_lupkes=.false. -l_sice_heatflux=.false. -!!l_stability_lupkes=.false. +beta_evap=1.0 +buddy_sea='On' +!!cdn_hw_sea=0.002 +!!cdn_max_sea=0.003 +dtice=2.0 +emis_sea=0.985 +emis_sice=0.976 +!!hcap_sea=2.0e6 +i_high_wind_drag='reduced_v1' +iseasurfalg='coare' +kappa_seasurf=0.5 +kappai=2.09 +kappai_snow=0.256 +l_10m_neut=.true. +l_iceformdrag_lupkes=.true. +l_sice_heatflux=.true. +!!l_stability_lupkes=.true. l_use_dtstar_sea=.false. -nice=0 -!!u_cdn_hw=0 -!!u_cdn_max=0 -!!z0h_specified=0 -!!z0m_specified=0 +nice=1 +!!u_cdn_hw=55.0 +!!u_cdn_max=33.0 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] -can_clump=0 -cansnowpft=.false. -i_basal_melting_opt='none' -i_grain_growth_opt='marshall' -i_relayer_opt='original' -n_lai_exposed=0 -unload_rate_u=0 +can_clump=8.0,4.0,1.0,1.0,1.0 +cansnowpft=.true.,.true.,.false.,.false.,.false. +i_basal_melting_opt='instant' +i_grain_growth_opt='taillandier' +i_relayer_opt='inverse' +n_lai_exposed=5*1.0 +rho_snow_fresh=109.0 +unload_rate_u=2.31e-6,2.31e-6,0.0,0.0,0.0 [!!namelist:jules_soil] -l_dpsids_dsdz=.false. -l_soil_sat_down=.false. +l_dpsids_dsdz=.true. +l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' -cor_mo_iter='lim_oblen' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 +cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' -formdrag='none' +formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. -l_vary_z0m_soil=.false. -srf_ex_cnv_gust=.false. +l_vary_z0m_soil=.true. +!!orog_drag_param=0.15 +srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] -nnvg=0 -npft=0 -soil=0 -!!urban=0 +brd_leaf=1 +c3_grass=3 +c4_grass=4 +ice=9 +lake=7 +ndl_leaf=2 +nnvg=4 +npft=5 +shrub=5 +soil=8 +!!urban=6 !!urban_canyon=0 !!urban_roof=0 [!!namelist:jules_urban] -!!anthrop_heat_scale=0 +!!anthrop_heat_scale=1.0 l_moruses_albedo=.false. l_moruses_emissivity=.false. l_moruses_rough=.false. @@ -676,29 +739,43 @@ l_moruses_storage=.false. !!l_moruses_storage_thin=.false. [!!namelist:jules_vegetation] -can_rad_mod='one' -l_limit_canhc=.false. -l_spec_veg_z0=.false. +can_rad_mod='six' +l_limit_canhc=.true. +l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. l_stabilise_bl=.false. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] -!!a_ratio_exp=0 -!!a_ratio_fac=0 +!!a_ratio_exp=-0.2707 +!!a_ratio_fac=0.0517 !!c_r_correl=0.9 !!casim_cdnc_opt='fixed' ci_input=14.3 cic_input=1024.0 droplet_tpr=.false. -!!fcrit=0 +!!fcrit=1.0 !!graupel_scheme='none' heavy_rain_evap_fac=0.0 !!i_update_precfrac='homog' @@ -706,78 +783,96 @@ heavy_rain_evap_fac=0.0 !!l_proc_fluxes=.false. microphysics_casim=.false. !!mp_dz_scal=2.0 -!!ndrop_surf=0 -!!nscalesf=0 -!!nsigmasf=0 -!!orog_block=.false. -!!orog_rain=.false. -!!orog_rime=.false. -!!prog_tnuc=.false. -!!qcl_rime=0 -!!shape_rime=.false. -turb_gen_mixph=.false. -!!z_surf=0 +!!ndrop_surf=50.0e6 +!!nscalesf=1.0 +!!nsigmasf=2.82843 +!!orog_block=.true. +!!orog_rain=.true. +!!orog_rime=.true. +!!prog_tnuc=.true. +!!qcl_rime=1.0e-4 +!!shape_rime=.true. +turb_gen_mixph=.true. +!!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. -!!jacobi_relaxation=0 -mixed_solver_a_tol=1.0e-21 +!!jacobi_relaxation=0.5 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] -!!leonard_kl=0 +!!leonard_kl=2.0 leonard_term=.false. -!!method='3d_smag' -!!mix_factor=0 +!!method='blend_1dbl_fa' +!!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='' -multigrid_chain_nitems=0 +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' +multigrid_chain_nitems=4 +n_coarsesmooth=4 +n_postsmooth=2 +n_presmooth=2 +smooth_relaxation=0.8 + +[!!namelist:multires_coupling] +aerosol_mesh_name='aerosol' +coarse_aerosol_transport=.false. +coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] -!!arg_periapsis=0 -!!arg_periapsis_inc=0 -!!eccentricity=0 -!!eccentricity_inc=0 -elements='user' -!!epoch=0 -!!fixed_azimuth_angle=0 -!!fixed_zenith_angle=0 -!!hour_angle=0 -!!hour_angle_inc=0 -!!mean_anomaly=0 -!!mean_anomaly_inc=0 -!!obliquity=0 -!!obliquity_inc=0 -observer_lat=0 -observer_lon=0 -!!semimajor_axis=0 -!!semimajor_axis_inc=0 -spin='user' +!!arg_periapsis=1.796767421 +!!arg_periapsis_inc=0.0 +!!eccentricity=1.6710222E-02 +!!eccentricity_inc=0.0 +elements='earth_fixed' +!!epoch=2451545.0 +!!fixed_azimuth_angle=0.0 +!!fixed_zenith_angle=0.0 +!!hour_angle=0.0 +!!hour_angle_inc=0.0 +!!mean_anomaly=-0.037278428 +!!mean_anomaly_inc=0.01720278179 +!!obliquity=0.0 +!!obliquity_inc=0.0 +observer_lat=0.0 +observer_lon=0.0 +!!semimajor_axis=1.0 +!!semimajor_axis_inc=0.0 +spin='earth_day' [!!namelist:orographic_drag] -cd_flow_blocking=0 -fr_crit_gwd=0 -fr_sat_gwd=0 -gwd_scaling=0 -mountain_height_scaling=0 -orographic_blocking_heating=.false. -orographic_gwd_heating=.false. -vertical_smoothing=.false. +cd_flow_blocking=4.0 +fr_crit_gwd=4.0 +fr_sat_gwd=0.25 +gwd_scaling=0.7 +include_moisture='lowmoist' +mountain_height_scaling=2.6 +orographic_blocking_heating=.true. +orographic_gwd_heating=.true. +vertical_smoothing=.true. [namelist:orography] orog_init_option='ancil' @@ -785,87 +880,89 @@ orog_init_option='ancil' [!!namelist:orography_agnesi_cartesian] direction='x' -half_width_x=0 -half_width_y=0 -mountain_height=0 -x_centre=0 -y_centre=0 +half_width_x=10.0 +half_width_y=10.0 +mountain_height=100.0 +x_centre=0.0 +y_centre=0.0 [!!namelist:orography_agnesi_spherical] -half_width=0 -lambda_centre_dec=0 -lambda_focus_dec=0 -mountain_height=0 -phi_centre_dec=0 -phi_focus_dec=0 +half_width=2500.0 +lambda_centre_dec=1.5 +lambda_focus_dec=1.5 +mountain_height=100.0 +phi_centre_dec=0.0 +phi_focus_dec=0.3333 [!!namelist:orography_bell_cartesian] -direction='x' -half_width_x=0 -half_width_y=0 -mountain_height=0 -x_centre=0 -y_centre=0 +direction='xy' +half_width_x=1000.0 +half_width_y=1000.0 +mountain_height=400.0 +x_centre=0.0 +y_centre=0.0 [!!namelist:orography_bell_spherical] -lambda_centre1=0 -lambda_centre2=0 -mountain_height=0 -phi_centre1=0 -phi_centre2=0 -radius_lat=0 -radius_lon=0 +lambda_centre1=0.0 +lambda_centre2=0.0 +mountain_height=100.0 +phi_centre1=0.0 +phi_centre2=0.0 +radius_lat=10.0 +radius_lon=10.0 [!!namelist:orography_dcmip200_spherical] -lambda_centre_dec=0 -mountain_height=0 -osc_half_width_dec=0 -phi_centre_dec=0 -radius_dec=0 +lambda_centre_dec=1.5 +mountain_height=2000.0 +osc_half_width_dec=0.0625 +phi_centre_dec=0.0 +radius_dec=0.75 [!!namelist:orography_schar_cartesian] direction='x' -half_width_x=0 -half_width_y=0 -mountain_height=0 -wavelength=0 -x_centre=0 -y_centre=0 +half_width_x=20.0 +half_width_y=20.0 +mountain_height=250.0 +wavelength=20.0 +x_centre=0.0 +y_centre=0.0 [!!namelist:orography_schar_spherical] -half_width=0 -lambda_centre_dec=0 -mountain_height=0 -phi_centre_dec=0 -wavelength=0 +half_width=5000.0 +lambda_centre_dec=0.25 +mountain_height=250.0 +phi_centre_dec=0.0 +wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 -!!limit_drag_incs=.false. -!!lowest_level='constant' -!!ls_ppn_segment=0 +gw_segment=0 +limit_drag_incs=.false. +!!lowest_level='gradient' +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.false. -!!sample_physics_winds=.false. -!!smagorinsky_placement='fast' +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. +!!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -877,58 +974,40 @@ scaling_factor=1.0 [!!namelist:radiation] !!cloud_entrapment='zero' -!!cloud_inhomogeneity='homogeneous' -!!cloud_overlap='maximum_random' -cloud_representation='no_cloud' -!!cloud_vertical_decorr=0 -!!constant_droplet_effective_radius=0 -!!droplet_effective_radius='default' -i_cloud_ice_type_lw=0 -!!i_cloud_ice_type_lwinc=0 -i_cloud_ice_type_sw=0 -!!i_cloud_ice_type_swinc=0 -i_cloud_liq_type_lw=0 -!!i_cloud_liq_type_lwinc=0 -i_cloud_liq_type_sw=0 -!!i_cloud_liq_type_swinc=0 -l_cfc113_lw=.false. -l_cfc11_lw=.false. -l_cfc12_lw=.false. -l_ch4_lw=.false. -l_ch4_sw=.false. -l_co2_lw=.false. -l_co2_sw=.false. -l_continuum_lw=.false. -l_continuum_sw=.false. -l_h2o_lw=.false. -l_h2o_sw=.false. -l_hcfc22_lw=.false. -l_hfc134a_lw=.false. +!!cloud_inhomogeneity='mcica' +!!cloud_overlap='exponential_random' +cloud_representation='combined' +!!cloud_vertical_decorr=10000.0 +!!constant_droplet_effective_radius=7.0E-6 +!!droplet_effective_radius='liu' +i_cloud_ice_type_lw=11 +!!i_cloud_ice_type_lwinc=11 +i_cloud_ice_type_sw=11 +!!i_cloud_ice_type_swinc=11 +i_cloud_liq_type_lw=5 +!!i_cloud_liq_type_lwinc=5 +i_cloud_liq_type_sw=5 +!!i_cloud_liq_type_swinc=5 l_inc_radstep=.false. -l_n2o_lw=.false. -l_n2o_sw=.false. -l_o2_sw=.false. -l_o3_lw=.false. -l_o3_sw=.false. l_planet_grey_surface=.false. -l_rayleigh_sw=.false. -l_trans_zen_correction=.false. -!!liu_aparam=0 -!!liu_bparam=0 -mcica_data_file='' -!!n_horiz_ang=0 -!!n_horiz_layer=0 -!!n_inc_radstep=0 -n_radstep=0 -!!planet_albedo=0 -!!planet_emissivity=0 -scatter_method_lw='full' -!!scatter_method_lwinc='full' -spectral_file_lw='' -!!spectral_file_lwinc='' -spectral_file_sw='' -!!spectral_file_swinc='' -topography='flat' +l_rayleigh_sw=.true. +l_trans_zen_correction=.true. +!!liu_aparam=0.077 +!!liu_bparam=-0.1365 +mcica_data_file='spec/mcica_data' +!!n_horiz_ang=16 +!!n_horiz_layer=1 +!!n_inc_radstep=1 +n_radstep=2 +!!planet_albedo=0.06 +!!planet_emissivity=0.985 +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' +spectral_file_lw='spec/sp_lw_ga9' +!!spectral_file_lwinc='spec/sp_lw_cloud9' +spectral_file_sw='spec/sp_sw_ga9' +!!spectral_file_swinc='spec/sp_sw_cloud9' +topography='slope' [namelist:radiative_gases] !!cfc113_clim_fcg_levls=0 @@ -941,26 +1020,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1032,8 +1111,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1050,8 +1129,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1060,7 +1139,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1087,10 +1166,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1098,58 +1177,58 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] !!fail_on_non_converged=.false. gcrk=18 -!!jacobi_relaxation=0 -maximum_iterations=50 +!!jacobi_relaxation=0.5 +maximum_iterations=7 method='chebyshev' monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] -!!function_amplitude_e=0 -!!function_amplitude_h=0 +!!function_amplitude_e=200 +!!function_amplitude_h=400 !!function_name_fluxes='constant' !!function_name_sst='constant' -!!function_period_e=0 -!!function_period_h=0 +!!function_period_e=300 +!!function_period_h=600 !!function_phase_e=0 !!function_phase_h=0 !!internal_flux_method='uniform' !!internal_flux_value=0.0 -!!length_of_day=0 -!!profile_size=0 -!!profile_size_sst=0 -!!sea_surf_temps=0 -!!specified_flux_e=0 -!!specified_flux_h=0 +!!length_of_day=10.0 +!!profile_size=1 +!!profile_size_sst=1 +!!sea_surf_temps=300.0 +!!specified_flux_e=300. +!!specified_flux_h=300. !!surf_temp_forcing='none' !!time_data=0 !!time_data_sst=0 -!!time_of_max_flux=0 +!!time_of_max_flux=15.0 !!time_units='seconds' !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=0 -ussp_heating=.false. -ussp_launch_factor=0 -wavelstar=0 +add_cgw=.true. +!!cgw_scale_factor=0.86 +ussp_heating=.true. +ussp_launch_factor=1.2 +wavelstar=4300.0 [!!namelist:star] -stellar_constant=0 -stellar_radius=0 +stellar_constant=1361.0 +stellar_radius=6.957e8 [!!namelist:stochastic_physics] !!blpert_add_vertical_shape=.true. @@ -1163,44 +1242,44 @@ stellar_radius=0 !!blpert_only_near_edge=.true. !!blpert_time_correlation=.true. blpert_type='off' -ens_memb=0 -!!rp_bl_a_ent_1=0 -!!rp_bl_a_ent_shr=0 -!!rp_bl_a_ent_shr_max=0 -!!rp_bl_cbl_mix_fac=0 -!!rp_bl_cld_top_diffusion=0 -!!rp_bl_min_mix_length=0 -!!rp_bl_neutral_mix_length=0 -!!rp_bl_ricrit=0 -!!rp_bl_smag_coef=0 -!!rp_bl_stable_ri_coef=0 -!!rp_callfreq=0 +ens_memb=${ENSEMBLE_MEMBER} +!!rp_bl_a_ent_1=0.100,0.230,0.400 +!!rp_bl_a_ent_shr=1.6 +!!rp_bl_a_ent_shr_max=5.0 +!!rp_bl_cbl_mix_fac=0.0,0.5,1.0 +!!rp_bl_cld_top_diffusion=0.500,0.850,1.500 +!!rp_bl_min_mix_length=8.0,40.0,120.0 +!!rp_bl_neutral_mix_length=0.03,0.15,0.45 +!!rp_bl_ricrit=0.25,1.0,2.0 +!!rp_bl_smag_coef=0.01,0.2,1.0 +!!rp_bl_stable_ri_coef=5.000,10.000,20.000 +!!rp_callfreq=300 !!rp_cycle_in=.false. !!rp_cycle_out=.false. -!!rp_cycle_tm=0 -!!rp_decorr_ts=0 -!!rp_lsfc_alnir= -!!rp_lsfc_alnir_max= -!!rp_lsfc_alnir_min= -!!rp_lsfc_alpar= -!!rp_lsfc_alpar_max= -!!rp_lsfc_alpar_min= -!!rp_lsfc_lai_mult=0 -!!rp_lsfc_lai_mult_max=0 -!!rp_lsfc_lai_mult_min=0 -!!rp_lsfc_omega= -!!rp_lsfc_omega_max= -!!rp_lsfc_omega_min= -!!rp_lsfc_omnir= -!!rp_lsfc_omnir_max= -!!rp_lsfc_omnir_min= +!!rp_cycle_tm=43200 +!!rp_decorr_ts=604800.0 +!!rp_lsfc_alnir=0.341,0.272,0.369,0.368,0.395 +!!rp_lsfc_alnir_max=0.341,0.272,0.369,0.368,0.395 +!!rp_lsfc_alnir_min=0.341,0.272,0.369,0.368,0.395 +!!rp_lsfc_alpar=0.057,0.041,0.071,0.083,0.074 +!!rp_lsfc_alpar_max=0.057,0.041,0.071,0.083,0.074 +!!rp_lsfc_alpar_min=0.057,0.041,0.071,0.083,0.074 +!!rp_lsfc_lai_mult=5*1.0 +!!rp_lsfc_lai_mult_max=5*1.0 +!!rp_lsfc_lai_mult_min=5*1.0 +!!rp_lsfc_omega=0.101,0.083,0.132,0.135,0.115 +!!rp_lsfc_omega_max=0.101,0.083,0.132,0.135,0.115 +!!rp_lsfc_omega_min=0.101,0.083,0.132,0.135,0.115 +!!rp_lsfc_omnir=0.788,0.545,0.864,0.787,0.785 +!!rp_lsfc_omnir_max=0.788,0.545,0.864,0.787,0.785 +!!rp_lsfc_omnir_min=0.788,0.545,0.864,0.787,0.785 !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 -!!rp_lsfc_z0_soil=0,0,0 +!!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=0 -!!rp_lsfc_z0hm_pft_max=0 -!!rp_lsfc_z0hm_pft_min=0 -!!rp_lsfc_z0hm_soil=0,0,0 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= !!rp_lsfc_z0v_min= @@ -1208,44 +1287,44 @@ ens_memb=0 !!rp_mp_ice_fspd=6000000.0,6000000.0,6000000.0 !!rp_mp_mp_czero=10.0,10.0,10.0 !!rp_mp_mpof=0.5,0.5,0.5 -!!rp_mp_ndrop_surf=0 +!!rp_mp_ndrop_surf=2.0e+07,5.0e+07,10.0e+07 !!rp_mp_snow_fspd=12.0,12.0,12.0 -!!rp_ran_max=0 +!!rp_ran_max=30 !!skeb_add_increments=.false. -!!skeb_br=0 -!!skeb_convective_dissipation=.false. -!!skeb_convective_dissipation_factor=0 -!!skeb_convective_dissipation_modulation=.false. -!!skeb_decorrelation_time=0 -!!skeb_div_du='fd' -!!skeb_level_bottom=0 -!!skeb_level_bottom_cap=0 -!!skeb_level_top=0 -!!skeb_n_smoothing_iters=0 -!!skeb_numerical_dissipation='none' -!!skeb_numerical_dissipation_factor=0 +!!skeb_br=0.03 +!!skeb_convective_dissipation=.true. +!!skeb_convective_dissipation_factor=1.0 +!!skeb_convective_dissipation_modulation=.true. +!!skeb_decorrelation_time=2.00e+4 +!!skeb_div_du='fe' +!!skeb_level_bottom=2 +!!skeb_level_bottom_cap=2 +!!skeb_level_top=50 +!!skeb_n_smoothing_iters=3 +!!skeb_numerical_dissipation='fd' +!!skeb_numerical_dissipation_factor=2.0 !!skeb_rot_du='fd' -!!skeb_total_backscatter=0 -!!spt_add_increments=.false. -!!spt_convection_cfl_limit=.false. -!!spt_decorrelation_time=0 -!!spt_level_begin_tapering_bottom=0 -!!spt_level_begin_tapering_top=0 -!!spt_level_bottom=0 -!!spt_level_top=0 -!!spt_moisture_conservation=.false. -!!spt_mse_conservation=.false. -!!spt_n_smoothing_iters=0 -!!spt_orog_forcing_pattern_thresh=0 -!!spt_stddev_convection=0 -!!spt_stddev_microphysics=0 -!!spt_stddev_orog_thres=0 -!!spt_stddev_radiation=0 -!!spt_use_convection=.false. -!!spt_use_microphysics=.false. -!!spt_use_radiation=.false. -stph_n_max=0 -stph_n_min=0 +!!skeb_total_backscatter=1.00e-4 +!!spt_add_increments=.true. +!!spt_convection_cfl_limit=.true. +!!spt_decorrelation_time=2.00e+4 +!!spt_level_begin_tapering_bottom=15 +!!spt_level_begin_tapering_top=41 +!!spt_level_bottom=9 +!!spt_level_top=45 +!!spt_moisture_conservation=.true. +!!spt_mse_conservation=.true. +!!spt_n_smoothing_iters=3 +!!spt_orog_forcing_pattern_thresh=0.5 +!!spt_stddev_convection=1.73 +!!spt_stddev_microphysics=1.73 +!!spt_stddev_orog_thres=500. +!!spt_stddev_radiation=1.73 +!!spt_use_convection=.true. +!!spt_use_microphysics=.true. +!!spt_use_radiation=.true. +stph_n_max=60 +stph_n_min=20 use_random_parameters=.false. use_skeb=.false. use_spt=.false. @@ -1275,29 +1354,31 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2016-01-01 15:00:00' -calendar_start='2016-01-01 15:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' -timestep_end='20' -timestep_start='1' +timestep_end='$RESTART_STOP' +timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 -dt=3600.0 -inner_iterations=2 +dt=$DT +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' spinup_alpha=.false. -!!spinup_period=0 +!!spinup_period=0.0 tau_r=1.0 tau_t=1.0 tau_u=0.55 [namelist:transport] adjust_theta=.false. -!!adjust_theta_above=0.0 +!!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1314,14 +1395,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1331,27 +1413,28 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' -scheme=5*1 +scheme=5*3 si_outer_transport='none' slice_order='parabola' special_edges_monotone=5*1 -splitting=5*1 +splitting=5*2 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. -!!wind_mono_top_depth=0 +!!wind_mono_top_depth=5 [namelist:validity_test] -number_gamma_values=0 -update_ls_frequency=0 +number_gamma_values=2 +update_ls_frequency=1 [!!namelist:vapour_forcing] coordinate='height' diff --git a/rose-stem/app/generate_weights/bin/generate_weights_lfric2lfric.py b/rose-stem/app/generate_weights/bin/generate_weights_lfric2lfric.py index ec28ce2e0..f74ab7beb 100755 --- a/rose-stem/app/generate_weights/bin/generate_weights_lfric2lfric.py +++ b/rose-stem/app/generate_weights/bin/generate_weights_lfric2lfric.py @@ -145,8 +145,8 @@ def run_exe(arg, outfile, style): DST_GRID = GRID() DST_GRID = get_env_info(DST_GRID, 'DST') DST_GRID = get_data(DST_GRID) - # end processing destination grid validate_input(DST_GRID) + # end processing destination grid print('DESTINATION grid ') print('Save SRC -> DST grid info') diff --git a/rose-stem/app/gravity_wave/file/iodef.xml b/rose-stem/app/gravity_wave/file/iodef.xml index 93ceb52c1..b7156638d 100644 --- a/rose-stem/app/gravity_wave/file/iodef.xml +++ b/rose-stem/app/gravity_wave/file/iodef.xml @@ -103,7 +103,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/gravity_wave/rose-app.conf b/rose-stem/app/gravity_wave/rose-app.conf index 8e7d37bc9..a32534553 100644 --- a/rose-stem/app/gravity_wave/rose-app.conf +++ b/rose-stem/app/gravity_wave/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-gravity_wave/vn3.0 +meta=lfric-gravity_wave/vn3.1 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -34,6 +34,7 @@ source=namelist:base_mesh = namelist:initialization = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -241,6 +242,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [!!namelist:damping_layer] @@ -569,6 +571,9 @@ write_minmax_tseries=.false. l_hydrology=.true. !!l_var_rainfrac=.false. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -652,14 +657,33 @@ l_soil_sat_down=.true. l_vg_soil=.true. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='lim_oblen' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -691,7 +715,7 @@ l_limit_canhc=.false. l_spec_veg_z0=.false. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -856,16 +880,17 @@ panel_decomposition='auto' partitioner='planar' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 !!limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -875,7 +900,7 @@ configure_segments=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1289,6 +1314,7 @@ tau_u=0.0 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj='upwind' diff --git a/rose-stem/app/gungho_model/file/file_def_initial.xml b/rose-stem/app/gungho_model/file/file_def_initial.xml index 2b1050253..42cf3bfec 100644 --- a/rose-stem/app/gungho_model/file/file_def_initial.xml +++ b/rose-stem/app/gungho_model/file/file_def_initial.xml @@ -13,6 +13,8 @@ + + diff --git a/rose-stem/app/gungho_model/file/iodef_climate.xml b/rose-stem/app/gungho_model/file/iodef_climate.xml index e4bc3a888..429b0160e 100644 --- a/rose-stem/app/gungho_model/file/iodef_climate.xml +++ b/rose-stem/app/gungho_model/file/iodef_climate.xml @@ -41,7 +41,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/gungho_model/file/iodef_lam.xml b/rose-stem/app/gungho_model/file/iodef_lam.xml index 8c3417421..c85d7503a 100644 --- a/rose-stem/app/gungho_model/file/iodef_lam.xml +++ b/rose-stem/app/gungho_model/file/iodef_lam.xml @@ -42,7 +42,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/gungho_model/file/iodef_nwp.xml b/rose-stem/app/gungho_model/file/iodef_nwp.xml index 6c8a69c76..cc2410726 100644 --- a/rose-stem/app/gungho_model/file/iodef_nwp.xml +++ b/rose-stem/app/gungho_model/file/iodef_nwp.xml @@ -41,7 +41,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/gungho_model/opt/rose-app-suite_controlled.conf b/rose-stem/app/gungho_model/opt/rose-app-suite_controlled.conf index c3789d266..81be83085 100644 --- a/rose-stem/app/gungho_model/opt/rose-app-suite_controlled.conf +++ b/rose-stem/app/gungho_model/opt/rose-app-suite_controlled.conf @@ -24,6 +24,11 @@ use_xios_io=${USE_XIOS_IO} [namelist:logging] run_log_level='${LOG_LEVEL}' +[namelist:partitioning] +panel_decomposition='${PANEL_DECOMP}' +panel_xproc=${XPROC} +panel_yproc=${YPROC} + [namelist:time] timestep_end='${RESTART_STOP}' timestep_start='${RESTART_START}' diff --git a/rose-stem/app/gungho_model/rose-app.conf b/rose-stem/app/gungho_model/rose-app.conf index d4bc76fa1..f1cb5c754 100644 --- a/rose-stem/app/gungho_model/rose-app.conf +++ b/rose-stem/app/gungho_model/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-gungho_model/vn3.0 +meta=lfric-gungho_model/vn3.1 [command] default=$CORE_ROOT_DIR/bin/tweak_iodef ; \ @@ -44,6 +44,7 @@ source=namelist:base_mesh = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -261,6 +262,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [!!namelist:damping_layer] @@ -589,6 +591,9 @@ write_minmax_tseries=.false. l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -672,14 +677,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -711,7 +735,7 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -881,16 +905,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 !!limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -900,7 +925,7 @@ configure_segments=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1314,6 +1339,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.true. broken_w2_projection=.false. calculate_detj='upwind' diff --git a/rose-stem/app/jedi_forecast/file/iodef.xml b/rose-stem/app/jedi_forecast/file/iodef.xml index 5af66f247..7a100a000 100644 --- a/rose-stem/app/jedi_forecast/file/iodef.xml +++ b/rose-stem/app/jedi_forecast/file/iodef.xml @@ -66,6 +66,8 @@ + + @@ -294,7 +296,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/jedi_forecast/opt/rose-app-gh-si-for-linear.conf b/rose-stem/app/jedi_forecast/opt/rose-app-gh-si-for-linear.conf index c2178fe4b..c25ab8db7 100644 --- a/rose-stem/app/jedi_forecast/opt/rose-app-gh-si-for-linear.conf +++ b/rose-stem/app/jedi_forecast/opt/rose-app-gh-si-for-linear.conf @@ -31,6 +31,7 @@ pert_centre=120.0 [namelist:linear] fixed_ls=.false. +transport_efficiency=.false. [namelist:mixed_solver] gcrk=6 diff --git a/rose-stem/app/jedi_forecast/rose-app.conf b/rose-stem/app/jedi_forecast/rose-app.conf index 3848d4ba0..42c17cee6 100644 --- a/rose-stem/app/jedi_forecast/rose-app.conf +++ b/rose-stem/app/jedi_forecast/rose-app.conf @@ -1,4 +1,4 @@ -meta=jedi_forecast/vn3.0 +meta=jedi_forecast/vn3.0_t108 [command] default=$CORE_ROOT_DIR/bin/tweak_iodef ; \ @@ -50,6 +50,7 @@ source=namelist:jedi_lfric_tests = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -61,6 +62,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = namelist:mixed_solver = (namelist:mixing) @@ -266,6 +268,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] @@ -599,6 +602,7 @@ io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-4 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] @@ -621,6 +625,9 @@ variables='theta','rho','exner' l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -704,14 +711,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -747,9 +773,21 @@ fixed_ls=.true. l_stabilise_bl=.false. ls_read_w2h=.false. pert_option='analytic' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -919,16 +957,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -938,7 +977,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1352,6 +1391,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. ageofair_reset_level=10 broken_w2_projection=.false. diff --git a/rose-stem/app/jedi_forecast_pseudo/file/iodef.xml b/rose-stem/app/jedi_forecast_pseudo/file/iodef.xml index 54b92f876..5aade9f56 100644 --- a/rose-stem/app/jedi_forecast_pseudo/file/iodef.xml +++ b/rose-stem/app/jedi_forecast_pseudo/file/iodef.xml @@ -84,7 +84,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf index 8d5864da0..5734e167c 100644 --- a/rose-stem/app/jedi_forecast_pseudo/rose-app.conf +++ b/rose-stem/app/jedi_forecast_pseudo/rose-app.conf @@ -1,4 +1,4 @@ -meta=jedi_forecast_pseudo/vn3.0 +meta=jedi_forecast_pseudo/vn3.0_t108 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -48,6 +48,7 @@ source=namelist:jedi_lfric_tests = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -59,6 +60,7 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = namelist:mixed_solver = (namelist:mixing) @@ -264,6 +266,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] @@ -595,6 +598,7 @@ io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-4 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] @@ -615,6 +619,9 @@ variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -698,14 +705,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -741,9 +767,21 @@ fixed_ls=.true. l_stabilise_bl=.false. ls_read_w2h=.false. pert_option='analytic' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -913,16 +951,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -932,7 +971,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1346,6 +1385,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. ageofair_reset_level=10 broken_w2_projection=.false. diff --git a/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml b/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml index 7d20e4080..4a65814b5 100644 --- a/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml +++ b/rose-stem/app/jedi_id_tlm_tests/file/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + @@ -144,6 +146,11 @@ + + + + + @@ -234,6 +241,8 @@ + + @@ -280,6 +289,8 @@ + + @@ -421,6 +432,7 @@ + @@ -431,7 +443,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 000000000..125a4758d --- /dev/null +++ b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-default.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-default.conf deleted file mode 100644 index e69de29bb..000000000 diff --git a/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 000000000..379986682 --- /dev/null +++ b/rose-stem/app/jedi_id_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,26 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_id_tlm_tests/file/iodef.xml + +[namelist:io] +diagnostic_frequency=8 + +[namelist:jedi_geometry] +io_calender_start='2018-04-14T21:00:00' + +[namelist:jedi_increment] +inc_time='2018-04-14 21:00:00' + +[namelist:jedi_pseudo_model] +initial_time='2018-04-14T21:00:00' + +[namelist:jedi_state] +state_time='2018-04-14 21:00:00' + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2018-04-14 21:00:00' +calendar_start='2018-04-14 21:00:00' diff --git a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf index 1049af568..dc2a904a2 100644 --- a/rose-stem/app/jedi_id_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_id_tlm_tests/rose-app.conf @@ -1,4 +1,4 @@ -meta=jedi_id_tlm_tests/vn3.0 +meta=jedi_id_tlm_tests/vn3.0_t108 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -23,13 +23,19 @@ source=namelist:jedi_lfric_tests = namelist:jedi_linear_model = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -40,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -50,6 +57,7 @@ source=namelist:jedi_lfric_tests = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -61,30 +69,35 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) - = (namelist:theta_relax) = namelist:time = namelist:timestepping = namelist:transport @@ -105,24 +118,24 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -185,7 +198,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -205,14 +218,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -267,6 +280,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] @@ -317,7 +331,7 @@ stretching_method='smooth' !!aerosols_ancil_path='' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' -ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${ancil_resolution}' +ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' checkpoint_stem_name='' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' @@ -378,7 +392,7 @@ diag_stem_name='' !!o3_ancil_path='' !!oh_ancil_path='' orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -410,7 +424,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -420,7 +434,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -434,16 +448,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 +!!fail_on_non_converged=.false. +gcrk=8 !!jacobi_relaxation=0.5 -method='bicgstab' -monitor_convergence=.true. +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 -si_pressure_maximum_iterations=40 -si_pressure_tolerance=1.0e-15 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 +si_pressure_maximum_iterations=400 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -453,7 +467,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -500,15 +514,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -520,22 +534,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -545,8 +559,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -574,7 +588,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -590,7 +604,7 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' +io_calender_start='2021-06-02T00:00:00' io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' @@ -598,12 +612,13 @@ io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' +inc_time='2021-06-02 00:00:00' initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-4 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] @@ -614,20 +629,23 @@ incremental_wind_interpolation=.true. nl_time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', + ='m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -653,7 +671,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -692,8 +710,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -711,14 +729,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -753,10 +790,24 @@ l_spec_veg_z0=.true. fixed_ls=.true. l_stabilise_bl=.false. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -781,40 +832,40 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. !!jacobi_relaxation=0.5 -mixed_solver_a_tol=1.0e-21 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 -si_maximum_iterations=7 +si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -822,9 +873,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -919,33 +978,34 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 -!!limit_drag_incs=.false. +gw_segment=0 +limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.true. -!!sample_physics_winds=.true. -!!sample_physics_winds_correction=.false. +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -984,12 +1044,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1003,26 +1063,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1094,8 +1154,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1112,8 +1172,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1122,7 +1182,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1149,10 +1209,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1160,23 +1220,23 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] -fail_on_non_converged=.false. +!!fail_on_non_converged=.false. gcrk=18 !!jacobi_relaxation=0.5 -maximum_iterations=50 +maximum_iterations=7 method='chebyshev' -monitor_convergence=.true. +monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] !!function_amplitude_e=200 @@ -1203,10 +1263,10 @@ tolerance=1.0e-18 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1259,9 +1319,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1306,7 +1366,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1337,8 +1397,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2018-04-14 21:00:00' -calendar_start='2018-04-14 21:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1346,7 +1406,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' @@ -1359,7 +1419,9 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1376,14 +1438,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1393,7 +1456,7 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' scheme=5*1 si_outer_transport='none' @@ -1403,10 +1466,11 @@ splitting=5*1 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. !!wind_mono_top_depth=5 diff --git a/rose-stem/app/jedi_lfric_tests/file/iodef.xml b/rose-stem/app/jedi_lfric_tests/file/iodef.xml index 07b94bab0..dfb5b1345 100644 --- a/rose-stem/app/jedi_lfric_tests/file/iodef.xml +++ b/rose-stem/app/jedi_lfric_tests/file/iodef.xml @@ -50,6 +50,11 @@ + + + + + @@ -140,6 +145,8 @@ + + @@ -186,6 +193,8 @@ + + @@ -302,7 +311,7 @@ - + @@ -327,6 +336,7 @@ + @@ -337,7 +347,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 000000000..125a4758d --- /dev/null +++ b/rose-stem/app/jedi_lfric_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9.conf deleted file mode 100644 index 90d207a80..000000000 --- a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9.conf +++ /dev/null @@ -1,3 +0,0 @@ -[file:iodef_temp.xml] -mode=auto -source=$ROSE_SUITE_DIR/app/jedi_lfric_tests/file/iodef.xml diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 000000000..0e183de1c --- /dev/null +++ b/rose-stem/app/jedi_lfric_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,20 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_lfric_tests/file/iodef.xml + +[namelist:files] +ls_directory='$BIG_DATA_DIR/tangent-linear/PullRequest182' +ls_filename='final_ls_with_land' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' +start_dump_filename='final_pert' + +[namelist:io] +diagnostic_frequency=8 + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2016-01-01 15:00:00' +calendar_start='2016-01-01 15:00:00' diff --git a/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf b/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf index 6c3a2714d..645167002 100644 --- a/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf +++ b/rose-stem/app/jedi_lfric_tests/opt/rose-app-runge-kutta.conf @@ -20,7 +20,6 @@ start_dump_directory='' start_dump_filename='' [namelist:finite_element] -coord_system='xyz' vorticity_in_w1=.true. [namelist:formulation] @@ -28,12 +27,28 @@ dlayer_on=.false. dry_static_adjust=.false. eos_method='projected' exner_from_eos=.true. +l_multigrid=.false. moisture_formulation='dry' !!theta_moist_source=.false. [namelist:helmholtz_solver] -gcrk=18 -si_pressure_tolerance=1.0e-6 +preconditioner='tridiagonal' + +[namelist:idealised] +test='gravity_wave' + +[namelist:initial_density] +r1=0.0 +r2=0.0 +x1=0.0 +x2=0.0 + +[namelist:initial_temperature] +pert_centre=-60.0 + +[namelist:initial_wind] +smp_init_wind=.false. +u0=0.0 [namelist:initialization] init_option='analytic' @@ -45,16 +60,24 @@ diagnostic_frequency=20 [namelist:linear] fixed_ls=.false. +l_stabilise_bl=.false. pert_option='analytic' +transport_efficiency=.false. [namelist:mixed_solver] gcrk=6 mixed_solver_a_tol=1.0e-6 si_tolerance=1.0e-3 +[!!namelist:multigrid] +chain_mesh_tags='','','','' + [namelist:orography] orog_init_option='none' +[namelist:partitioning] +generate_inner_halos=.true. + [namelist:planet] scaling_factor=125.0 @@ -74,9 +97,6 @@ method='rk' cfl_mol_1d_stab=2.0 cfl_mol_2d_stab=2.0 cfl_mol_3d_stab=2.0 -log_space=5*.false. max_vert_cfl_calc='uniform' -reversible=.false. runge_kutta_method='ssp4' -slice_order='cubic' !!wind_mono_top_depth=0 diff --git a/rose-stem/app/jedi_lfric_tests/rose-app.conf b/rose-stem/app/jedi_lfric_tests/rose-app.conf index a683eda8f..07157baf5 100644 --- a/rose-stem/app/jedi_lfric_tests/rose-app.conf +++ b/rose-stem/app/jedi_lfric_tests/rose-app.conf @@ -1,4 +1,4 @@ -meta=jedi_lfric_tests/vn3.0 +meta=jedi_lfric_tests/vn3.0_t108 [command] default=rose env-cat iodef_temp.xml -o iodef.xml; $LAUNCH_SCRIPT/launch-exe @@ -20,17 +20,22 @@ source=namelist:jedi_lfric_tests = namelist:jedi_geometry = namelist:jedi_state = namelist:jedi_increment - = namelist:jedi_pseudo_model = namelist:jedi_linear_model - = namelist:jedi_model + = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -41,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -51,6 +57,7 @@ source=namelist:jedi_lfric_tests = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -62,27 +69,33 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) = namelist:time @@ -105,17 +118,17 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 @@ -185,7 +198,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -205,14 +218,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -267,12 +280,13 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] dl_base=40000.0 dl_str=0.05 -dl_type='latitude' +dl_type='standard' [namelist:departure_points] horizontal_limit='cap' @@ -317,7 +331,7 @@ stretching_method='smooth' !!aerosols_ancil_path='' !!albedo_nir_ancil_path='' !!albedo_vis_ancil_path='' -ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/Quagga/${ancil_resolution}/n96e_l70' +ancil_directory='$BIG_DATA_DIR/ancils/basic-gal/yak/${RESOLUTION}' checkpoint_stem_name='$CYLC_SUITE_SHARE_DIR/data/restartGungho_$ROSE_TASK_NAME' !!cloud_drop_no_conc_ancil_path='' !!coarse_ancil_directory='' @@ -372,13 +386,13 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='$BIG_DATA_DIR/tangent-linear/PullRequest182' +ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' !!oh_ancil_path='' -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -388,8 +402,8 @@ orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' !!soil_dust_ancil_path='' !!soil_rough_ancil_path='' !!sst_ancil_path='' -start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -start_dump_filename='final_pert' +start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +start_dump_filename='final_2021060200-2021060207.pert' !!surface_frac_ancil_path='' !!urban_ancil_path='' @@ -410,7 +424,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -440,7 +454,7 @@ gcrk=8 method='prec_only' monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' +preconditioner='multigrid' si_pressure_a_tol=1.0e-8 si_pressure_maximum_iterations=400 si_pressure_tolerance=1.0e-4 @@ -453,7 +467,7 @@ si_pressure_tolerance=1.0e-4 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -500,15 +514,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -520,22 +534,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -545,8 +559,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -574,7 +588,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -590,47 +604,51 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' -io_path_inc_read='' +io_calender_start='2021-06-02T00:00:00' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' +inc_time='2021-06-02 00:00:00' initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-4 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] test_field='theta' [namelist:jedi_linear_model] -incremental_wind_interpolation=.true. +incremental_wind_interpolation=.false. nl_time_step='P0DT1H0M0S' [namelist:jedi_model] time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' + ='m_v','m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -656,7 +674,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -695,8 +713,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -714,14 +732,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -756,10 +793,24 @@ l_spec_veg_z0=.true. fixed_ls=.true. l_stabilise_bl=.false. ls_read_w2h=.false. +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 pert_option='file' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -784,9 +835,9 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 @@ -799,7 +850,7 @@ guess_np1=.false. mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. -reference_reset_time=3600. +reference_reset_time=3600.0 si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' @@ -809,15 +860,15 @@ split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -825,9 +876,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -922,23 +981,24 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -948,7 +1008,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -987,12 +1047,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1006,26 +1066,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1097,8 +1157,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1115,8 +1175,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1125,7 +1185,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1206,10 +1266,10 @@ tolerance=1.0e-6 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1262,9 +1322,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1309,7 +1369,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1340,8 +1400,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2016-01-01 15:00:00' -calendar_start='2016-01-01 15:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1349,7 +1409,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' @@ -1362,6 +1422,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. ageofair_reset_level=10 broken_w2_projection=.false. diff --git a/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml b/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml index 7d20e4080..4a65814b5 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml +++ b/rose-stem/app/jedi_tlm_forecast_tl/file/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + @@ -144,6 +146,11 @@ + + + + + @@ -234,6 +241,8 @@ + + @@ -280,6 +289,8 @@ + + @@ -421,6 +432,7 @@ + @@ -431,7 +443,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG.conf new file mode 100644 index 000000000..125a4758d --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG_op.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG_op.conf new file mode 100644 index 000000000..8e18ae5fd --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-C12_MG_op.conf @@ -0,0 +1,7 @@ +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='${MESH_DIR}/mesh_C12_MG_op' +!!fplane= +prepartitioned=.true. + +[!!namelist:partitioning] diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-default.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-default.conf deleted file mode 100644 index e69de29bb..000000000 diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 000000000..065a444b6 --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,26 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_tlm_forecast_tl/file/iodef.xml + +[namelist:io] +diagnostic_frequency=8 + +[namelist:jedi_geometry] +io_calender_start='2018-04-14T21:00:00' + +[namelist:jedi_increment] +inc_time='2018-04-14 21:00:00' + +[namelist:jedi_pseudo_model] +initial_time='2018-04-14T21:00:00' + +[namelist:jedi_state] +state_time='2018-04-14 21:00:00' + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2018-04-14 21:00:00' +calendar_start='2018-04-14 21:00:00' diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-rrt_equals_dt.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-rrt_equals_dt.conf new file mode 100644 index 000000000..3d9745645 --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-rrt_equals_dt.conf @@ -0,0 +1,2 @@ +[namelist:mixed_solver] +reference_reset_time=$DT diff --git a/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-semi_strict_solver.conf b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-semi_strict_solver.conf new file mode 100644 index 000000000..d9c5499fd --- /dev/null +++ b/rose-stem/app/jedi_tlm_forecast_tl/opt/rose-app-semi_strict_solver.conf @@ -0,0 +1,9 @@ +[namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-3 + +[namelist:mixed_solver] +mixed_solver_a_tol=1.0e-21 +si_tolerance=1.0e-3 + +[namelist:timestepping] +outer_iterations=1 diff --git a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf index ba5167caf..b446f4c69 100644 --- a/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf +++ b/rose-stem/app/jedi_tlm_forecast_tl/rose-app.conf @@ -1,4 +1,4 @@ -meta=jedi_tlm_forecast_tl/vn3.0 +meta=jedi_tlm_forecast_tl/vn3.0_t108 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -23,13 +23,19 @@ source=namelist:jedi_lfric_tests = namelist:jedi_linear_model = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -40,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -50,6 +57,7 @@ source=namelist:jedi_lfric_tests = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -61,26 +69,33 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) + = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) = namelist:time @@ -103,24 +118,24 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -183,7 +198,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -203,14 +218,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -265,6 +280,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] @@ -376,7 +392,7 @@ diag_stem_name='' !!o3_ancil_path='' !!oh_ancil_path='' orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -408,7 +424,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -418,7 +434,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -432,16 +448,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 +!!fail_on_non_converged=.false. +gcrk=8 !!jacobi_relaxation=0.5 -method='bicgstab' -monitor_convergence=.true. +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 -si_pressure_maximum_iterations=40 -si_pressure_tolerance=1.0e-15 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 +si_pressure_maximum_iterations=400 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -451,7 +467,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -498,15 +514,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -518,22 +534,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -543,8 +559,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -572,7 +588,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -588,43 +604,48 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' +io_calender_start='2021-06-02T00:00:00' io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' io_path_state_write='write_file' -io_setup_increment=.true. +io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' -initialise_via_read=.true. +inc_time='2021-06-02 00:00:00' +initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-4 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] test_field='theta' [namelist:jedi_linear_model] +incremental_wind_interpolation=.false. nl_time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', + ='m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -650,7 +671,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -689,8 +710,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -708,14 +729,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -750,10 +790,24 @@ l_spec_veg_z0=.true. fixed_ls=.true. l_stabilise_bl=.false. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -778,40 +832,40 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. !!jacobi_relaxation=0.5 -mixed_solver_a_tol=1.0e-21 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 -si_maximum_iterations=7 +si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -819,9 +873,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -916,33 +978,34 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 -!!limit_drag_incs=.false. +gw_segment=0 +limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.true. -!!sample_physics_winds=.true. -!!sample_physics_winds_correction=.false. +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -981,12 +1044,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1000,26 +1063,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1091,8 +1154,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1109,8 +1172,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1119,7 +1182,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1146,10 +1209,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1157,23 +1220,23 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] -fail_on_non_converged=.false. +!!fail_on_non_converged=.false. gcrk=18 !!jacobi_relaxation=0.5 -maximum_iterations=50 +maximum_iterations=7 method='chebyshev' -monitor_convergence=.true. +monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] !!function_amplitude_e=200 @@ -1200,10 +1263,10 @@ tolerance=1.0e-18 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1256,9 +1319,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1303,7 +1366,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1334,8 +1397,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2018-04-14 21:00:00' -calendar_start='2018-04-14 21:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1343,7 +1406,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' @@ -1356,7 +1419,9 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1373,14 +1438,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1390,7 +1456,7 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' scheme=5*1 si_outer_transport='none' @@ -1400,10 +1466,11 @@ splitting=5*1 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. !!wind_mono_top_depth=5 diff --git a/rose-stem/app/jedi_tlm_tests/file/iodef.xml b/rose-stem/app/jedi_tlm_tests/file/iodef.xml index 7d20e4080..4a65814b5 100644 --- a/rose-stem/app/jedi_tlm_tests/file/iodef.xml +++ b/rose-stem/app/jedi_tlm_tests/file/iodef.xml @@ -41,6 +41,7 @@ + @@ -55,6 +56,7 @@ + @@ -144,6 +146,11 @@ + + + + + @@ -234,6 +241,8 @@ + + @@ -280,6 +289,8 @@ + + @@ -421,6 +432,7 @@ + @@ -431,7 +443,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG.conf new file mode 100644 index 000000000..125a4758d --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C12_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C12_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C12_MG' +!!fplane= diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG_op.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG_op.conf new file mode 100644 index 000000000..8e18ae5fd --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C12_MG_op.conf @@ -0,0 +1,7 @@ +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='${MESH_DIR}/mesh_C12_MG_op' +!!fplane= +prepartitioned=.true. + +[!!namelist:partitioning] diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-C224_MG.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C224_MG.conf new file mode 100644 index 000000000..1814a4708 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-C224_MG.conf @@ -0,0 +1,8 @@ +[file:mesh_C224_MG.nc] +mode=auto +source=$MESH_DIR/mesh_C224_MG.nc + +[namelist:base_mesh] +!!f_lat_deg= +file_prefix='mesh_C224_MG' +!!fplane= diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-default.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-default.conf deleted file mode 100644 index e69de29bb..000000000 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf index 3f2af7e5b..ffd315be0 100644 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-dry.conf @@ -2,3 +2,8 @@ moisture_formulation='dry' moisture_in_solver=.false. !!theta_moist_source=.false. + +[namelist:section_choice] +!!aerosol='none' +!!cloud='none' +!!methane_oxidation=.false. diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf new file mode 100644 index 000000000..ccd55de3b --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c12.conf @@ -0,0 +1,28 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml + +[namelist:io] +diagnostic_frequency=8 + +[namelist:jedi_geometry] +io_calender_start='2018-04-14T21:00:00' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' + +[namelist:jedi_increment] +inc_time='2018-04-14 21:00:00' + +[namelist:jedi_pseudo_model] +initial_time='2018-04-14T21:00:00' + +[namelist:jedi_state] +state_time='2018-04-14 21:00:00' + +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 + +[namelist:time] +calendar_origin='2018-04-14 21:00:00' +calendar_start='2018-04-14 21:00:00' diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c224.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c224.conf new file mode 100644 index 000000000..dfe2b916d --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-nwp_gal9_c224.conf @@ -0,0 +1,3 @@ +[file:iodef_temp.xml] +mode=auto +source=$ROSE_SUITE_DIR/app/jedi_tlm_tests/file/iodef.xml diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-real_increment.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-real_increment.conf new file mode 100644 index 000000000..aea74c8fa --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-real_increment.conf @@ -0,0 +1,5 @@ +[namelist:jedi_geometry] +io_setup_increment=.true. + +[namelist:jedi_increment] +initialise_via_read=.true. diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-relaxed_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-relaxed_solver.conf deleted file mode 100644 index b435c2bc3..000000000 --- a/rose-stem/app/jedi_tlm_tests/opt/rose-app-relaxed_solver.conf +++ /dev/null @@ -1,15 +0,0 @@ -[namelist:helmholtz_solver] -gcrk=8 -si_pressure_a_tol=1.0e-8 -si_pressure_maximum_iterations=400 -si_pressure_tolerance=1.0e-4 - -[namelist:mixed_solver] -gcrk=6 -mixed_solver_a_tol=0.0 -si_maximum_iterations=10 -si_tolerance=1.0e-5 - -[namelist:solver] -maximum_iterations=7 -tolerance=1.0e-6 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-rrt_equals_dt.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-rrt_equals_dt.conf new file mode 100644 index 000000000..3d9745645 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-rrt_equals_dt.conf @@ -0,0 +1,2 @@ +[namelist:mixed_solver] +reference_reset_time=$DT diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf new file mode 100644 index 000000000..4af6d3cf1 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-semi_strict_solver.conf @@ -0,0 +1,9 @@ +[namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-2 + +[namelist:mixed_solver] +mixed_solver_a_tol=1.0e-21 +si_tolerance=1.0e-3 + +[namelist:timestepping] +outer_iterations=1 diff --git a/rose-stem/app/jedi_tlm_tests/opt/rose-app-strict_solver.conf b/rose-stem/app/jedi_tlm_tests/opt/rose-app-strict_solver.conf new file mode 100644 index 000000000..77270e0f5 --- /dev/null +++ b/rose-stem/app/jedi_tlm_tests/opt/rose-app-strict_solver.conf @@ -0,0 +1,15 @@ +[namelist:helmholtz_solver] +gcrk=18 +si_pressure_a_tol=0 +si_pressure_tolerance=1.0e-15 + +[namelist:mixed_solver] +fail_on_non_converged=.false. +gcrk=10 +mixed_solver_a_tol=1.0e-21 +si_maximum_iterations=100 +si_tolerance=1.0e-21 + +[namelist:solver] +maximum_iterations=50 +tolerance=1.0e-18 diff --git a/rose-stem/app/jedi_tlm_tests/rose-app.conf b/rose-stem/app/jedi_tlm_tests/rose-app.conf index 8e0df8026..6e8c2a776 100644 --- a/rose-stem/app/jedi_tlm_tests/rose-app.conf +++ b/rose-stem/app/jedi_tlm_tests/rose-app.conf @@ -1,4 +1,4 @@ -meta=jedi_tlm_tests/vn3.0 +meta=jedi_tlm_tests/vn3.0_t108 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -23,13 +23,19 @@ source=namelist:jedi_lfric_tests = namelist:jedi_linear_model = namelist:jedi_pseudo_model = namelist:jedi_lfric_settings + = (namelist:aerosol) = namelist:base_mesh + = (namelist:blayer) = namelist:boundaries = namelist:checks = namelist:section_choice + = (namelist:cloud) + = (namelist:chemistry) + = (namelist:convection) + = (namelist:cosp) = (namelist:damping_layer) = (namelist:departure_points) - = namelist:energy_correction + = (namelist:energy_correction) = (namelist:external_forcing) = namelist:extrusion = (namelist:files) @@ -40,6 +46,7 @@ source=namelist:jedi_lfric_tests = (namelist:iau_addinf_io(:)) = (namelist:iau_ainc_io(:)) = (namelist:iau_bcorr_io(:)) + = (namelist:iau) = (namelist:idealised) = (namelist:ideal_surface) = namelist:initialization @@ -50,6 +57,7 @@ source=namelist:jedi_lfric_tests = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -61,30 +69,35 @@ source=namelist:jedi_lfric_tests = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging + = (namelist:microphysics) = namelist:mixed_solver - = (namelist:mixing) + = namelist:mixing = (namelist:multigrid) = (namelist:multires_coupling) = namelist:esm_couple + = (namelist:orbit) = namelist:orography = (namelist:orography_agnesi_cartesian) = (namelist:orography_agnesi_spherical) - = (namelist:orography_bell_cartesian) - = (namelist:orography_bell_spherical) = (namelist:orography_dcmip200_spherical) = (namelist:orography_schar_cartesian) = (namelist:orography_schar_spherical) = namelist:partitioning = (namelist:physics) = namelist:planet + = (namelist:radiation) = namelist:radiative_gases + = (namelist:spectral_gwd) + = (namelist:orographic_drag) = namelist:solver = (namelist:specified_surface) + = (namelist:star) = (namelist:stochastic_physics) + = (namelist:surface) = (namelist:temp_tend_data) = (namelist:theta_relax) - = (namelist:theta_relax) = namelist:time = namelist:timestepping = namelist:transport @@ -105,24 +118,24 @@ easyaerosol_cdnc=.false. easyaerosol_lw=.false. easyaerosol_sw=.false. !!emissions='GC5' -glomap_mode='off' +glomap_mode='dust_and_clim' !!horiz_d=2.25 -!!l_radaer=.false. +!!l_radaer=.true. murk=.false. !!murk_lbc=.false. !!murk_prognostic=.false. !!murk_source_scaling=1.0 !!murk_visibility=.false. !!n_radaer_step=1 -!!prec_file='' -sulphuric_strat_climatology=.false. +!!prec_file='precalc/RADAER_pcalc.ukca' +sulphuric_strat_climatology=.true. !!sulphuric_strat_column=1.86604e-6 ukca_mode_seg_size=4 !!us_am=1.45 [namelist:base_mesh] !!f_lat_deg=45.0 -file_prefix='mesh.nc' +file_prefix='mesh' !!fplane=.false. geometry='spherical' prepartitioned=.false. @@ -185,7 +198,7 @@ limited_area=.false. !!rim_width_ns=1 !!solver_boundary_depth=1 !!transport_boundary_depth=6 -transport_overwrite_freq='split_step' +transport_overwrite_freq='final' [namelist:checks] limit_cfl=.false. @@ -205,14 +218,14 @@ chem_scheme='none' !!fjx_spec_file='FJX_spec_Nov11.dat' !!flexchem_opt='bs1999' i_chem_timestep_halvings=0 -!!i_ukca_chem_version=0 +!!i_ukca_chem_version=111 !!l_ukca_asad_full=.false. -!!l_ukca_linox_scaling=.false. -!!l_ukca_quasinewton=.false. +!!l_ukca_linox_scaling= +!!l_ukca_quasinewton= !!l_ukca_ro2_ntp=.false. -!!lightnox_scale_fac=0 +!!lightnox_scale_fac= !!photol_scheme='off' -!!top_bdy_opt='no_overwrt' +!!top_bdy_opt='' [!!namelist:cloud] !!cff_spread_rate=1.0e-5 @@ -267,6 +280,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] @@ -378,7 +392,7 @@ diag_stem_name='' !!o3_ancil_path='' !!oh_ancil_path='' orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog' -!!orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' +!!orography_subgrid_ancil_path='' !!ozone_ancil_path='' !!plant_func_ancil_path='' !!sea_ancil_path='' @@ -410,7 +424,7 @@ exner_from_eos=.false. horizontal_physics_predictor=.false. horizontal_transport_predictor=.false. init_exner_bt=.true. -l_multigrid=.false. +l_multigrid=.true. lagged_orog=.true. moisture_formulation='traditional' moisture_in_solver=.true. @@ -420,7 +434,7 @@ shallow=.true. si_momentum_equation=.false. theta_moist_source=.false. use_multires_coupling=.false. -use_physics=.false. +use_physics=.true. use_wavedynamics=.true. vector_invariant=.false. @@ -434,16 +448,16 @@ profile_data_v=0.0 times=0.0 [namelist:helmholtz_solver] -fail_on_non_converged=.false. -gcrk=18 +!!fail_on_non_converged=.false. +gcrk=8 !!jacobi_relaxation=0.5 -method='bicgstab' -monitor_convergence=.true. +method='prec_only' +monitor_convergence=.false. normalise=.true. -preconditioner='tridiagonal' -si_pressure_a_tol=0 -si_pressure_maximum_iterations=40 -si_pressure_tolerance=1.0e-15 +preconditioner='multigrid' +si_pressure_a_tol=1.0e-8 +si_pressure_maximum_iterations=400 +si_pressure_tolerance=1.0e-4 [namelist:iau] !!iau_ainc_multifile=.false. @@ -453,7 +467,7 @@ si_pressure_tolerance=1.0e-15 !!iau_tendency_ainc=.false. !!iau_tendency_bcorr=.true. !!iau_tendency_pertinc=.false. -!!iau_ts_start=0 +!!iau_ts_start=1 !!iau_use_addinf=.false. !!iau_use_bcorr=.false. !!iau_use_level_one_temp=.false. @@ -500,15 +514,15 @@ f_lon_deg=0.0 perturb_init=.false. !!perturb_magnitude=0 !!perturb_seed=0 -test='gravity_wave' +test='none' [namelist:initial_density] density_background=0.1 density_max=2.0 -r1=0.0 -r2=0.0 -x1=0.0 -x2=0.0 +r1=0.4 +r2=0.4 +x1=0.4 +x2=-0.4 y1=0.0 y2=0.0 z1=0.0 @@ -520,22 +534,22 @@ surface_pressure=1000.0e2 [namelist:initial_temperature] bvf_square=0.0001 -pert_centre=120.0 +pert_centre=60.0 pert_width_scaling=1.0 perturb='none' -!!profile_data=300.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=300.0,300.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 theta_surf=300.0 [namelist:initial_vapour] -!!profile_data=0.0 -!!profile_heights=0.0 -!!profile_size=1 +!!profile_data=0.0,0.0 +!!profile_heights=0.0,10.0e3 +!!profile_size=2 [namelist:initial_wind] nl_constant=0.0 -profile='none' +profile='constant_uv' !!profile_data_u=0.0 !!profile_data_v=0.0 !!profile_data_w=0.0 @@ -545,8 +559,8 @@ profile='none' !!profile_size_w=1 sbr_angle_lat=0.0 sbr_angle_lon=0.0 -smp_init_wind=.false. -u0=0.0 +smp_init_wind=.true. +u0=2.0 v0=0.0 wind_time_period=0.0 @@ -574,7 +588,7 @@ checkpoint_write=.false. counter_output_suffix='counter.txt' diag_active_files='lfric_diag' diag_always_on_sampling=.false. -diagnostic_frequency=8 +diagnostic_frequency=12 !!end_of_run_checkpoint=.true. file_convention='UGRID' multifile_io=.false. @@ -590,44 +604,48 @@ write_fluxes=.false. write_minmax_tseries=.false. [namelist:jedi_geometry] -io_calender_start='2018-04-14T21:00:00' -io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/pert_fields/lfric_diag' -io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Ticket354/ls_fields/jedi_trajectory' +io_calender_start='2021-06-02T00:00:00' +io_path_inc_read='$BIG_DATA_DIR/jedi-lfric/Issue126/C224_lfric_diag' +io_path_state_read='$BIG_DATA_DIR/jedi-lfric/Issue126/C224_jedi_trajectory' io_path_state_write='write_file' io_setup_increment=.false. io_time_step='P0DT1H0M0S' [namelist:jedi_increment] -inc_time='2018-04-14 21:00:00' +inc_time='2021-06-02 00:00:00' initialise_via_read=.false. variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', ='m_cl','m_r','m_s' [namelist:jedi_lfric_settings] +adjoint_test_tolerance=1.0e-4 forecast_length='P0DT6H0M0S' [namelist:jedi_lfric_tests] test_field='theta' [namelist:jedi_linear_model] -incremental_wind_interpolation=.true. +incremental_wind_interpolation=.false. nl_time_step='P0DT1H0M0S' [namelist:jedi_pseudo_model] -initial_time='2018-04-14T21:00:00' +initial_time='2021-06-02 00:00:00' number_of_steps=9 time_step='P0DT1H0M0S' [namelist:jedi_state] -state_time='2018-04-14 21:00:00' +state_time='2021-06-02 00:00:00' use_pseudo_model=.true. -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', - ='m_v','m_cl','m_r','m_s' +variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', + ='m_cl','m_r','m_s','land_fraction' [!!namelist:jules_hydrology] l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -653,7 +671,7 @@ kext_io=0.5,0.5,1.0,1.0,0.5 knl_io=5*0.2 omega_io=0.101,0.083,0.132,0.135,0.115 omnir_io=0.788,0.545,0.864,0.787,0.785 -z0hm_pft_io=1.65,1.65,0.1,0.1,0.1 +z0hm_pft_io=1.0,1.0,0.01,0.01,0.01 !!z0v_io=1.1,1.1,0.22,0.22,1.0 [!!namelist:jules_radiation] @@ -692,8 +710,8 @@ l_use_dtstar_sea=.false. nice=1 !!u_cdn_hw=55.0 !!u_cdn_max=33.0 -!!z0h_specified=0.01 -!!z0m_specified=0.1 +!!z0h_specified=0.0 +!!z0m_specified=0.0 [!!namelist:jules_snow] can_clump=8.0,4.0,1.0,1.0,1.0 @@ -711,14 +729,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -753,10 +790,24 @@ l_spec_veg_z0=.true. fixed_ls=.true. l_stabilise_bl=.false. ls_read_w2h=.false. -pert_option='analytic' +max_bl_stabilisation=0.75 +n_bl_levels_to_stabilise=15 +pert_option='file' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -781,40 +832,40 @@ microphysics_casim=.false. !!orog_block=.true. !!orog_rain=.true. !!orog_rime=.true. -!!prog_tnuc=.false. +!!prog_tnuc=.true. !!qcl_rime=1.0e-4 -!!shape_rime=.false. +!!shape_rime=.true. turb_gen_mixph=.true. !!z_surf=50.0 [namelist:mixed_solver] eliminate_variables='discrete' -fail_on_non_converged=.false. -gcrk=10 +fail_on_non_converged=.true. +gcrk=4 guess_np1=.false. !!jacobi_relaxation=0.5 -mixed_solver_a_tol=1.0e-21 +mixed_solver_a_tol=1.0e-3 monitor_convergence=.true. normalise=.true. reference_reset_time=3600.0 -si_maximum_iterations=7 +si_maximum_iterations=10 si_method='block_gcr' si_preconditioner='pressure' -si_tolerance=1.0e-21 +si_tolerance=1.0e-1 split_w=.true. [namelist:mixing] !!leonard_kl=2.0 leonard_term=.false. -!!method='blending' +!!method='blend_1dbl_fa' !!mix_factor=0.2 !!smag_l_calc='UseDx' smagorinsky=.false. viscosity=.false. viscosity_mu=0.0 -[!!namelist:multigrid] -chain_mesh_tags='','','','' +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2','multigrid_l3' multigrid_chain_nitems=4 n_coarsesmooth=4 n_postsmooth=2 @@ -822,9 +873,17 @@ n_presmooth=2 smooth_relaxation=0.8 [!!namelist:multires_coupling] -aerosol_mesh_name='dynamics' +aerosol_mesh_name='aerosol' coarse_aerosol_transport=.false. coarse_rad_aerosol=.false. +dynamics_mesh_name='dynamics' +!!lowest_order_aero_flag=.false. +multires_coupling_mesh_tags='dynamics' +multires_coupling_mode='test' +negative_correction='none' +physics_mesh_name='aerosol' +reconstruction='simple' +recovery_order='linear' [!!namelist:orbit] !!arg_periapsis=1.796767421 @@ -919,33 +978,34 @@ phi_centre_dec=0.0 wavelength=4000.0 [namelist:partitioning] -generate_inner_halos=.true. +generate_inner_halos=.false. panel_decomposition='auto' !!panel_xproc=1 !!panel_yproc=1 partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 -!!limit_drag_incs=.false. +gw_segment=0 +limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' -!!sample_physics_scalars=.true. -!!sample_physics_winds=.true. -!!sample_physics_winds_correction=.false. +sample_physics_scalars=.true. +sample_physics_winds=.true. +sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -984,12 +1044,12 @@ mcica_data_file='spec/mcica_data' n_radstep=2 !!planet_albedo=0.06 !!planet_emissivity=0.985 -scatter_method_lw='full' -!!scatter_method_lwinc='full' +scatter_method_lw='hybrid' +!!scatter_method_lwinc='approx' spectral_file_lw='spec/sp_lw_ga9' -!!spectral_file_lwinc='spec/sp_lw_cloud7' +!!spectral_file_lwinc='spec/sp_lw_cloud9' spectral_file_sw='spec/sp_sw_ga9' -!!spectral_file_swinc='spec/sp_sw_cloud7' +!!spectral_file_swinc='spec/sp_sw_cloud9' topography='slope' [namelist:radiative_gases] @@ -1003,26 +1063,26 @@ cfc113_rad_opt='off' !!cfc11_clim_fcg_nyears=0 !!cfc11_clim_fcg_rates=0 !!cfc11_clim_fcg_years=0 -!!cfc11_mix_ratio=1.110e-09 -cfc11_rad_opt='off' +cfc11_mix_ratio=1.110e-09 +cfc11_rad_opt='constant' !!cfc12_clim_fcg_levls=0 !!cfc12_clim_fcg_nyears=0 !!cfc12_clim_fcg_rates=0 !!cfc12_clim_fcg_years=0 -!!cfc12_mix_ratio=2.187e-09 -cfc12_rad_opt='off' +cfc12_mix_ratio=2.187e-09 +cfc12_rad_opt='constant' !!ch4_clim_fcg_levls=0 !!ch4_clim_fcg_nyears=0 !!ch4_clim_fcg_rates=0 !!ch4_clim_fcg_years=0 -!!ch4_mix_ratio=1.006e-06 -ch4_rad_opt='off' +ch4_mix_ratio=1.006e-06 +ch4_rad_opt='constant' !!co2_clim_fcg_levls=0 !!co2_clim_fcg_nyears=0 !!co2_clim_fcg_rates=0 !!co2_clim_fcg_years=0 -!!co2_mix_ratio=6.002e-04 -co2_rad_opt='off' +co2_mix_ratio=6.002e-04 +co2_rad_opt='constant' !!co_clim_fcg_levls=0 !!co_clim_fcg_nyears=0 !!co_clim_fcg_rates=0 @@ -1094,8 +1154,8 @@ n2_rad_opt='off' !!n2o_clim_fcg_nyears=0 !!n2o_clim_fcg_rates=0 !!n2o_clim_fcg_years=0 -!!n2o_mix_ratio=4.945e-07 -n2o_rad_opt='off' +n2o_mix_ratio=4.945e-07 +n2o_rad_opt='constant' !!na_clim_fcg_levls=0 !!na_clim_fcg_nyears=0 !!na_clim_fcg_rates=0 @@ -1112,8 +1172,8 @@ nh3_rad_opt='off' !!o2_clim_fcg_nyears=0 !!o2_clim_fcg_rates=0 !!o2_clim_fcg_years=0 -!!o2_mix_ratio=0.2314 -o2_rad_opt='off' +o2_mix_ratio=0.2314 +o2_rad_opt='constant' !!o3_clim_fcg_levls=0 !!o3_clim_fcg_nyears=0 !!o3_clim_fcg_rates=0 @@ -1122,7 +1182,7 @@ o2_rad_opt='off' !!o3_profile_data=0 !!o3_profile_heights=0.0 !!o3_profile_size=0 -o3_rad_opt='off' +o3_rad_opt='ancil' !!rb_clim_fcg_levls=0 !!rb_clim_fcg_nyears=0 !!rb_clim_fcg_rates=0 @@ -1149,10 +1209,10 @@ tio_rad_opt='off' vo_rad_opt='off' [namelist:section_choice] -!!aerosol='none' -!!boundary_layer='none' -!!chemistry='none' -!!cloud='none' +aerosol='none' +boundary_layer='none' +chemistry='none' +cloud='none' !!convection='none' dynamics='gungho' !!electric='none' @@ -1160,23 +1220,23 @@ external_forcing=.false. iau=.false. iau_sst=.false. iau_surf=.false. -!!methane_oxidation=.false. +methane_oxidation=.false. !!microphysics='none' -!!orographic_drag='none' -!!radiation='none' -!!spectral_gwd='none' -!!stochastic_physics='none' -!!surface='none' +orographic_drag='none' +radiation='none' +spectral_gwd='none' +stochastic_physics='none' +surface='none' [namelist:solver] -fail_on_non_converged=.false. +!!fail_on_non_converged=.false. gcrk=18 !!jacobi_relaxation=0.5 -maximum_iterations=50 +maximum_iterations=7 method='chebyshev' -monitor_convergence=.true. +monitor_convergence=.false. preconditioner='diagonal' -tolerance=1.0e-18 +tolerance=1.0e-6 [namelist:specified_surface] !!function_amplitude_e=200 @@ -1203,10 +1263,10 @@ tolerance=1.0e-18 !!time_units_sst='seconds' [!!namelist:spectral_gwd] -add_cgw=.false. -!!cgw_scale_factor=1.0 +add_cgw=.true. +!!cgw_scale_factor=0.86 ussp_heating=.true. -ussp_launch_factor=1.3 +ussp_launch_factor=1.2 wavelstar=4300.0 [!!namelist:star] @@ -1259,9 +1319,9 @@ ens_memb=${ENSEMBLE_MEMBER} !!rp_lsfc_orog_drag_param=0.15,0.15,0.15 !!rp_lsfc_z0_soil=1.0e-3,1.0e-3,1.0e-3 !!rp_lsfc_z0_urban_mult=1.0,1.0,1.0 -!!rp_lsfc_z0hm_pft=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_max=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 -!!rp_lsfc_z0hm_pft_min=1.65000,1.65000,1.00000e-2,1.00000e-2,1.00000e-1 +!!rp_lsfc_z0hm_pft=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_max=1.00,1.00,0.022,0.022,0.025 +!!rp_lsfc_z0hm_pft_min=1.00,1.00,0.022,0.022,0.025 !!rp_lsfc_z0hm_soil=2.0e-1,2.0e-1,2.0e-1 !!rp_lsfc_z0v= !!rp_lsfc_z0v_max= @@ -1306,7 +1366,7 @@ ens_memb=${ENSEMBLE_MEMBER} !!spt_use_convection=.true. !!spt_use_microphysics=.true. !!spt_use_radiation=.true. -stph_n_max=22 +stph_n_max=60 stph_n_min=20 use_random_parameters=.false. use_skeb=.false. @@ -1337,8 +1397,8 @@ timescale=1.0 [namelist:time] calendar='timestep' -calendar_origin='2018-04-14 21:00:00' -calendar_start='2018-04-14 21:00:00' +calendar_origin='2021-06-02 00:00:00' +calendar_start='2021-06-02 00:00:00' calendar_type='gregorian' timestep_end='$RESTART_STOP' timestep_start='$RESTART_START' @@ -1346,7 +1406,7 @@ timestep_start='$RESTART_START' [namelist:timestepping] alpha=0.55 dt=$DT -inner_iterations=2 +inner_iterations=1 method='semi_implicit' outer_iterations=2 runge_kutta_method='forward_euler' @@ -1359,7 +1419,9 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. +ageofair_reset_level=10 broken_w2_projection=.false. calculate_detj='upwind' cap_density_predictor=0.5 @@ -1376,14 +1438,15 @@ ffsl_inner_order=0 ffsl_outer_order=1 ffsl_splitting=5*1 ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud' +ffsl_vertical_order=2,2,1,2,2 +field_names='density','potential_temperature','wind','moisture', + ='con_tracer' fv_horizontal_order=2 fv_vertical_order=2 horizontal_method=5*1 horizontal_monotone=5*1 -log_space=5*.false. -max_vert_cfl_calc='uniform' +log_space=.true.,.true.,.false.,.false.,.false. +max_vert_cfl_calc='dep_point' min_val_abs_tol=-1.0e-12 min_val_max_iterations=10 min_val_method='iterative' @@ -1393,7 +1456,7 @@ operators='fv' panel_edge_high_order=.true. panel_edge_treatment='none' profile_size=5 -reversible=5*.false. +reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' scheme=5*1 si_outer_transport='none' @@ -1403,10 +1466,11 @@ splitting=5*1 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' +transport_ageofair=.false. use_density_predictor=.false. vertical_method=5*1 vertical_monotone=5*1 -vertical_monotone_order=5*1 +vertical_monotone_order=5*3 vertical_sl_order='cubic' wind_mono_top=.false. !!wind_mono_top_depth=5 diff --git a/rose-stem/app/jules/file/iodef.xml b/rose-stem/app/jules/file/iodef.xml index 2c047aa1d..b649bf0f4 100644 --- a/rose-stem/app/jules/file/iodef.xml +++ b/rose-stem/app/jules/file/iodef.xml @@ -101,7 +101,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/jules/rose-app.conf b/rose-stem/app/jules/rose-app.conf index 87b61ec08..52e040246 100644 --- a/rose-stem/app/jules/rose-app.conf +++ b/rose-stem/app/jules/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-jules/vn3.0 +meta=lfric-jules/vn3.1 [command] default=$CORE_ROOT_DIR/bin/tweak_iodef; \ @@ -51,6 +51,7 @@ source=(namelist:aerosol) = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -286,6 +287,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [!!namelist:damping_layer] @@ -658,6 +660,9 @@ write_minmax_tseries=.false. l_hydrology=.true. l_var_rainfrac=.true. +[namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -741,14 +746,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +beta_cnv_bl=0.04 cor_mo_iter='improved' +fd_hill_option='capped_lowhill' fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.true. +orog_drag_param=0.15 srf_ex_cnv_gust=.true. [namelist:jules_surface_types] @@ -780,7 +804,7 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -958,16 +982,17 @@ panel_decomposition='auto' partitioner='planar' [namelist:physics] -!!bl_segment=0 +bl_segment=0 blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -977,7 +1002,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1391,6 +1416,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.true. adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.true. ageofair_reset_level=10 broken_w2_projection=.false. diff --git a/rose-stem/app/lfric2lfric/file/axis_def_main.xml b/rose-stem/app/lfric2lfric/file/axis_def_main.xml index 83637bd76..ce91cb353 100644 --- a/rose-stem/app/lfric2lfric/file/axis_def_main.xml +++ b/rose-stem/app/lfric2lfric/file/axis_def_main.xml @@ -19,4 +19,5 @@ + diff --git a/rose-stem/app/lfric2lfric/file/iodef.xml b/rose-stem/app/lfric2lfric/file/iodef.xml index 192a1ab4c..0c4135087 100644 --- a/rose-stem/app/lfric2lfric/file/iodef.xml +++ b/rose-stem/app/lfric2lfric/file/iodef.xml @@ -61,7 +61,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric2lfric/file/iodef_lbc.xml b/rose-stem/app/lfric2lfric/file/iodef_lbc.xml new file mode 100644 index 000000000..3d2e14bd0 --- /dev/null +++ b/rose-stem/app/lfric2lfric/file/iodef_lbc.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + performance + 1.0 + + + + false + false + 50 + true + lfric2lfric lfric2lfric + + + + + diff --git a/rose-stem/app/lfric2lfric/file/iodef_orography.xml b/rose-stem/app/lfric2lfric/file/iodef_orography.xml index 0e4c444ff..f47e20e95 100644 --- a/rose-stem/app/lfric2lfric/file/iodef_orography.xml +++ b/rose-stem/app/lfric2lfric/file/iodef_orography.xml @@ -78,7 +78,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric2lfric/file/iodef_ral.xml b/rose-stem/app/lfric2lfric/file/iodef_ral.xml index 816d7c7e5..7f17ac192 100644 --- a/rose-stem/app/lfric2lfric/file/iodef_ral.xml +++ b/rose-stem/app/lfric2lfric/file/iodef_ral.xml @@ -386,7 +386,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric2lfric/file/iodef_ral3.xml b/rose-stem/app/lfric2lfric/file/iodef_ral3.xml index 737ad30d2..a75a2f338 100644 --- a/rose-stem/app/lfric2lfric/file/iodef_ral3.xml +++ b/rose-stem/app/lfric2lfric/file/iodef_ral3.xml @@ -162,7 +162,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric2lfric/opt/rose-app-lbc.conf b/rose-stem/app/lfric2lfric/opt/rose-app-lbc.conf new file mode 100644 index 000000000..629b93487 --- /dev/null +++ b/rose-stem/app/lfric2lfric/opt/rose-app-lbc.conf @@ -0,0 +1,21 @@ +[env] +RESTART_STOP=2 + +[file:iodef.xml] +source=$ROSE_SUITE_DIR/app/lfric2lfric/file/iodef_lbc.xml + +[file:source_file_lbc.nc] +mode=auto +source=$BIG_DATA_DIR/lfric2lfric/lfric_gal_diagnostics.nc + +[namelist:lfric2lfric] +destination_mesh_name='dynamics' +mode='lbc' +source_file_lbc='source_file_lbc' +source_mesh_name='C12' + +[namelist:time] +timestep_end='2' + +[namelist:timestepping] +dt=64800.0 diff --git a/rose-stem/app/lfric2lfric/rose-app.conf b/rose-stem/app/lfric2lfric/rose-app.conf index 704d66740..3da09230b 100644 --- a/rose-stem/app/lfric2lfric/rose-app.conf +++ b/rose-stem/app/lfric2lfric/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-lfric2lfric/vn3.0 +meta=lfric-lfric2lfric/vn3.1 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -20,6 +20,7 @@ source=namelist:extrusion = namelist:finite_element = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = namelist:logging = namelist:lfric2lfric = namelist:planet @@ -200,6 +201,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=0 [!!namelist:damping_layer] @@ -525,6 +527,9 @@ write_minmax_tseries=.false. l_hydrology=.false. !!l_var_rainfrac=.false. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0 albsnf_nvg_io=0 @@ -603,14 +608,33 @@ l_soil_sat_down=.false. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='lim_oblen' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.false. [!!namelist:jules_surface_types] @@ -641,9 +665,11 @@ destination_meshfile_prefix='input_mesh_faces' destination_topology='fully_periodic' dst_ancil_directory='' dst_orography_mean_ancil_path='' +mode='ics' origin_domain='global' prepartitioned_meshes=.false. regrid_method='map' +!!source_file_lbc='source_file_lbc' source_geometry='spherical' source_mesh_name='dynamics' source_meshfile_prefix='input_mesh_faces' @@ -652,9 +678,10 @@ src_ancil_directory='' src_orography_mean_ancil_path='' target_domain='global' !!weight_file='weight_file' +!!weight_file_lbc='weight_file_lbc' [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -823,16 +850,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 !!limit_drag_incs=.false. !!lowest_level='constant' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -841,7 +869,7 @@ configure_segments=.false. !!smagorinsky_placement='fast' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1254,6 +1282,7 @@ tau_u=0 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj='averaged' diff --git a/rose-stem/app/lfric2um/file/iodef.xml b/rose-stem/app/lfric2um/file/iodef.xml index 996edf98e..d10d607d4 100644 --- a/rose-stem/app/lfric2um/file/iodef.xml +++ b/rose-stem/app/lfric2um/file/iodef.xml @@ -79,7 +79,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric2um/file/iodef_performance.xml b/rose-stem/app/lfric2um/file/iodef_performance.xml index 482db56d7..32803f8b9 100644 --- a/rose-stem/app/lfric2um/file/iodef_performance.xml +++ b/rose-stem/app/lfric2um/file/iodef_performance.xml @@ -79,7 +79,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric2um/file/iodef_um_lam.xml b/rose-stem/app/lfric2um/file/iodef_um_lam.xml index 64d45d6ea..8144df871 100644 --- a/rose-stem/app/lfric2um/file/iodef_um_lam.xml +++ b/rose-stem/app/lfric2um/file/iodef_um_lam.xml @@ -73,7 +73,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_flexchem.xml b/rose-stem/app/lfric_atm/file/file_def_diags_flexchem.xml index a59d27821..7ffa3a145 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_flexchem.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_flexchem.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim.xml b/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim.xml index 495721086..c84243062 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim_chem.xml b/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim_chem.xml index c1d628a90..45ef77ea2 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim_chem.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_gal_clim_chem.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp.xml b/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp.xml index 1ba9df43e..6b88af04e 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_gal_nwp.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_idealised.xml b/rose-stem/app/lfric_atm/file/file_def_diags_idealised.xml index 7887a0d2a..76e92d218 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_idealised.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_idealised.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_idealised1.xml b/rose-stem/app/lfric_atm/file/file_def_diags_idealised1.xml index c0d16815f..089f2a300 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_idealised1.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_idealised1.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_ls_and_jedi.xml b/rose-stem/app/lfric_atm/file/file_def_diags_ls_and_jedi.xml index e4bbc8b2d..e45ce213d 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_ls_and_jedi.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_ls_and_jedi.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_name.xml b/rose-stem/app/lfric_atm/file/file_def_diags_name.xml index 1c25a9f43..fbe16d0e1 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_name.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_name.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_oper_nwp_gl.xml b/rose-stem/app/lfric_atm/file/file_def_diags_oper_nwp_gl.xml index 661368f12..fb5ee2571 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_oper_nwp_gl.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_oper_nwp_gl.xml @@ -1,7 +1,7 @@ - + @@ -132,7 +132,7 @@ - + @@ -194,7 +194,7 @@ - + @@ -231,7 +231,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_ral.xml b/rose-stem/app/lfric_atm/file/file_def_diags_ral.xml index 34951193f..baf6aa3ca 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_ral.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_ral.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_ral_ls_and_jedi.xml b/rose-stem/app/lfric_atm/file/file_def_diags_ral_ls_and_jedi.xml index affa03622..28457a494 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_ral_ls_and_jedi.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_ral_ls_and_jedi.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_var_ops.xml b/rose-stem/app/lfric_atm/file/file_def_diags_var_ops.xml index fc0cfc9c7..4d49c665b 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_var_ops.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_var_ops.xml @@ -2,7 +2,7 @@ - + @@ -29,7 +29,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -89,7 +89,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_diags_ver.xml b/rose-stem/app/lfric_atm/file/file_def_diags_ver.xml index 206cd0278..5e28ad32e 100644 --- a/rose-stem/app/lfric_atm/file/file_def_diags_ver.xml +++ b/rose-stem/app/lfric_atm/file/file_def_diags_ver.xml @@ -1,7 +1,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/file_def_initial_diags.xml b/rose-stem/app/lfric_atm/file/file_def_initial_diags.xml index c6ea03cdf..c1bca4231 100644 --- a/rose-stem/app/lfric_atm/file/file_def_initial_diags.xml +++ b/rose-stem/app/lfric_atm/file/file_def_initial_diags.xml @@ -1,7 +1,7 @@ - + diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_clim.xml b/rose-stem/app/lfric_atm/file/iodef_gal_clim.xml index 17279df2c..56891cca4 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_clim.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_clim.xml @@ -93,7 +93,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_clim_chem.xml b/rose-stem/app/lfric_atm/file/iodef_gal_clim_chem.xml index c16adb171..ea7ace037 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_clim_chem.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_clim_chem.xml @@ -175,7 +175,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp.xml index 4497d5ae5..43673f050 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp.xml @@ -97,7 +97,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml index 67e34a204..8eb90dd84 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_coarse_aero.xml @@ -97,7 +97,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_cycling.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_cycling.xml index 9dd58f867..e9ced2344 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_cycling.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_cycling.xml @@ -99,7 +99,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_hres.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_hres.xml index 17b6b1319..df5e2ad13 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_hres.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_hres.xml @@ -97,7 +97,10 @@ performance - 1.0 + 1.0 + + + 10485760 diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_oper.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_oper.xml index 6c1389875..30db97f76 100644 --- a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_oper.xml +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_oper.xml @@ -98,7 +98,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_gal_nwp_oper_hres.xml b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_oper_hres.xml new file mode 100644 index 000000000..b7e6d6824 --- /dev/null +++ b/rose-stem/app/lfric_atm/file/iodef_gal_nwp_oper_hres.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + performance + + + 10485760 + + + + true + 1 + false + + + + + diff --git a/rose-stem/app/lfric_atm/file/iodef_idealised.xml b/rose-stem/app/lfric_atm/file/iodef_idealised.xml index 9ec63cf7b..0c1c15767 100644 --- a/rose-stem/app/lfric_atm/file/iodef_idealised.xml +++ b/rose-stem/app/lfric_atm/file/iodef_idealised.xml @@ -70,7 +70,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_idealised_flexchem.xml b/rose-stem/app/lfric_atm/file/iodef_idealised_flexchem.xml index e3e6318f5..b5516c69a 100644 --- a/rose-stem/app/lfric_atm/file/iodef_idealised_flexchem.xml +++ b/rose-stem/app/lfric_atm/file/iodef_idealised_flexchem.xml @@ -71,7 +71,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_ls_and_jedi.xml b/rose-stem/app/lfric_atm/file/iodef_ls_and_jedi.xml index fed2ed7ed..c9252c608 100644 --- a/rose-stem/app/lfric_atm/file/iodef_ls_and_jedi.xml +++ b/rose-stem/app/lfric_atm/file/iodef_ls_and_jedi.xml @@ -95,7 +95,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_ral.xml b/rose-stem/app/lfric_atm/file/iodef_ral.xml index 3fec01cfa..773a01820 100644 --- a/rose-stem/app/lfric_atm/file/iodef_ral.xml +++ b/rose-stem/app/lfric_atm/file/iodef_ral.xml @@ -96,7 +96,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_ral_ls_and_jedi.xml b/rose-stem/app/lfric_atm/file/iodef_ral_ls_and_jedi.xml index fd5ee8c68..f801f9c2d 100644 --- a/rose-stem/app/lfric_atm/file/iodef_ral_ls_and_jedi.xml +++ b/rose-stem/app/lfric_atm/file/iodef_ral_ls_and_jedi.xml @@ -97,7 +97,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_test.xml b/rose-stem/app/lfric_atm/file/iodef_test.xml index 6d584583c..32e19c499 100644 --- a/rose-stem/app/lfric_atm/file/iodef_test.xml +++ b/rose-stem/app/lfric_atm/file/iodef_test.xml @@ -95,7 +95,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/file/iodef_test1.xml b/rose-stem/app/lfric_atm/file/iodef_test1.xml index fe8a05f31..79e093b55 100644 --- a/rose-stem/app/lfric_atm/file/iodef_test1.xml +++ b/rose-stem/app/lfric_atm/file/iodef_test1.xml @@ -95,7 +95,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_atm/opt/rose-app-camembert_case3_gj1214b.conf b/rose-stem/app/lfric_atm/opt/rose-app-camembert_case3_gj1214b.conf index 83a26c700..3b55fae60 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-camembert_case3_gj1214b.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-camembert_case3_gj1214b.conf @@ -130,6 +130,8 @@ init_option='analytic' [!!namelist:jules_hydrology] !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] + [!!namelist:jules_nvegparm] [!!namelist:jules_pftparm] @@ -153,7 +155,10 @@ init_option='analytic' [!!namelist:jules_soil] [!!namelist:jules_surface] +!!beta_cnv_bl=0.04 +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' +!!orog_drag_param=0.15 [!!namelist:jules_surface_types] !!urban=6 @@ -209,6 +214,7 @@ orog_init_option='none' !!lowest_level='gradient' !!microphysics_placement='slow' !!orographic_drag_placement='slow' +sample_physics_winds_correction=.true. !!spectral_gwd_placement='slow' [namelist:planet] diff --git a/rose-stem/app/lfric_atm/opt/rose-app-climate.conf b/rose-stem/app/lfric_atm/opt/rose-app-climate.conf index 09ba98a0c..06d90179a 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-climate.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-climate.conf @@ -18,6 +18,7 @@ l_ukca_asad_full=.false. [namelist:cosp] l_cosp=.true. +n_cosp_step=1 n_subcol_gen=64 [namelist:energy_correction] diff --git a/rose-stem/app/lfric_atm/opt/rose-app-da.conf b/rose-stem/app/lfric_atm/opt/rose-app-da.conf index cc0635967..bdd892382 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-da.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-da.conf @@ -6,8 +6,8 @@ iau_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/20210324T0600Z_um2lfric_iau_00 sea_ice_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/seaice_ugrid_postqa_fixed' snow_analysis_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/20210324T0600Z_glu_snow_um2lfric_fixed' sst_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/sst_ugrid_postqa_fixed' -start_dump_directory='$BIG_DATA_DIR/start_dumps/basic-gal/yak/Ticket354' -start_dump_filename='20210324T0000Z_lfric_ice_t+3' +start_dump_directory='$BIG_DATA_DIR/start_dumps/basic-gal/yak/PR202' +start_dump_filename='20210324T0000Z_lfric_ice_dust_t+3' [namelist:iau] iau_ainc_multifile=.false. diff --git a/rose-stem/app/lfric_atm/opt/rose-app-eda.conf b/rose-stem/app/lfric_atm/opt/rose-app-eda.conf index 0921925c3..ea7f076b4 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-eda.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-eda.conf @@ -11,8 +11,8 @@ iau_surf_path='$BIG_DATA_DIR/IAU/Global/um2lfric_landda' sea_ice_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/seaice_ugrid_postqa_fixed' snow_analysis_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/20210324T0600Z_glu_snow_um2lfric_fixed' sst_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/sst_ugrid_postqa_fixed' -start_dump_directory='$BIG_DATA_DIR/start_dumps/basic-gal/yak/Ticket354' -start_dump_filename='20210324T0000Z_lfric_ice_t+3' +start_dump_directory='$BIG_DATA_DIR/start_dumps/basic-gal/yak/PR202' +start_dump_filename='20210324T0000Z_lfric_ice_dust_t+3' [namelist:iau] iau_ainc_multifile=.true. diff --git a/rose-stem/app/lfric_atm/opt/rose-app-eda_jada.conf b/rose-stem/app/lfric_atm/opt/rose-app-eda_jada.conf index 3c33f1817..b0162aeba 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-eda_jada.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-eda_jada.conf @@ -7,8 +7,8 @@ iau_pert_path='$BIG_DATA_DIR/IAU/Global/iau_pertinc_start' sea_ice_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/seaice_ugrid_postqa_fixed' snow_analysis_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/20210324T0600Z_glu_snow_um2lfric_fixed' sst_ancil_path='$BIG_DATA_DIR/start_dumps/basic-gal/yak/sst_ugrid_postqa_fixed' -start_dump_directory='$BIG_DATA_DIR/start_dumps/basic-gal/yak/Ticket354' -start_dump_filename='20210324T0000Z_lfric_ice_t+3' +start_dump_directory='$BIG_DATA_DIR/start_dumps/basic-gal/yak/PR202' +start_dump_filename='20210324T0000Z_lfric_ice_dust_t+3' [namelist:iau] iau_ainc_multifile=.false. diff --git a/rose-stem/app/lfric_atm/opt/rose-app-gabls4.conf b/rose-stem/app/lfric_atm/opt/rose-app-gabls4.conf index ac138d5d5..30aa0c9c3 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-gabls4.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-gabls4.conf @@ -69,8 +69,10 @@ init_option='analytic' !!sst_source='ancillary' [namelist:jules_surface] +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' +!!orog_drag_param=0.15 [!!namelist:orographic_drag] diff --git a/rose-stem/app/lfric_atm/opt/rose-app-hd209458b.conf b/rose-stem/app/lfric_atm/opt/rose-app-hd209458b.conf index e05601b1a..570d397b6 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-hd209458b.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-hd209458b.conf @@ -142,6 +142,8 @@ init_option='analytic' [!!namelist:jules_hydrology] !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] + [!!namelist:jules_nvegparm] [!!namelist:jules_pftparm] @@ -165,7 +167,10 @@ init_option='analytic' [!!namelist:jules_soil] [!!namelist:jules_surface] +!!beta_cnv_bl=0.04 +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' +!!orog_drag_param=0.15 [!!namelist:jules_surface_types] !!urban=6 @@ -221,6 +226,7 @@ orog_init_option='none' !!lowest_level='gradient' !!microphysics_placement='slow' !!orographic_drag_placement='slow' +sample_physics_winds_correction=.true. !!spectral_gwd_placement='slow' [namelist:planet] diff --git a/rose-stem/app/lfric_atm/opt/rose-app-mg3.conf b/rose-stem/app/lfric_atm/opt/rose-app-mg3.conf new file mode 100644 index 000000000..ce1c2df6e --- /dev/null +++ b/rose-stem/app/lfric_atm/opt/rose-app-mg3.conf @@ -0,0 +1,3 @@ +[namelist:multigrid] +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2' +multigrid_chain_nitems=3 diff --git a/rose-stem/app/lfric_atm/opt/rose-app-oper_diags_hres.conf b/rose-stem/app/lfric_atm/opt/rose-app-oper_diags_hres.conf new file mode 100644 index 000000000..f999b8f91 --- /dev/null +++ b/rose-stem/app/lfric_atm/opt/rose-app-oper_diags_hres.conf @@ -0,0 +1,2 @@ +[file:iodef.xml] +source=$ROSE_SUITE_DIR/app/lfric_atm/file/iodef_gal_nwp_oper_hres.xml diff --git a/rose-stem/app/lfric_atm/opt/rose-app-physics_segmentation.conf b/rose-stem/app/lfric_atm/opt/rose-app-physics_segmentation.conf index af1ae7f82..854cf77af 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-physics_segmentation.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-physics_segmentation.conf @@ -1,6 +1,5 @@ [namelist:physics] bl_segment=16 -configure_segments=.true. gw_segment=32 ls_ppn_segment=32 ussp_segment=4 diff --git a/rose-stem/app/lfric_atm/opt/rose-app-rad_gas.conf b/rose-stem/app/lfric_atm/opt/rose-app-rad_gas.conf index 392c19dbd..917b83c2e 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-rad_gas.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-rad_gas.conf @@ -81,6 +81,8 @@ init_option='analytic' [!!namelist:jules_hydrology] !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] + [!!namelist:jules_nvegparm] [!!namelist:jules_pftparm] @@ -104,7 +106,10 @@ init_option='analytic' [!!namelist:jules_soil] [!!namelist:jules_surface] +!!beta_cnv_bl=0.04 +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' +!!orog_drag_param=0.15 [!!namelist:jules_surface_types] !!urban=6 diff --git a/rose-stem/app/lfric_atm/opt/rose-app-ral3_scm.conf b/rose-stem/app/lfric_atm/opt/rose-app-ral3_scm.conf index 2f916c2c7..03a0c847e 100644 --- a/rose-stem/app/lfric_atm/opt/rose-app-ral3_scm.conf +++ b/rose-stem/app/lfric_atm/opt/rose-app-ral3_scm.conf @@ -44,9 +44,11 @@ z0v_io=1.1,1.1,0.1,0.1,0.4 rho_snow_fresh=170.0 [namelist:jules_surface] +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.false. [namelist:microphysics] diff --git a/rose-stem/app/lfric_atm/rose-app.conf b/rose-stem/app/lfric_atm/rose-app.conf index d7f7988a5..bd907a551 100644 --- a/rose-stem/app/lfric_atm/rose-app.conf +++ b/rose-stem/app/lfric_atm/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-lfric_atm/vn3.0 +meta=lfric-lfric_atm/vn3.1 [command] default=$CORE_ROOT_DIR/bin/tweak_iodef; \ @@ -51,6 +51,7 @@ source=(namelist:aerosol) = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -286,6 +287,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] @@ -612,6 +614,9 @@ write_minmax_tseries=.false. l_hydrology=.true. l_var_rainfrac=.true. +[namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -695,14 +700,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +beta_cnv_bl=0.04 cor_mo_iter='improved' +fd_hill_option='capped_lowhill' fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.true. +orog_drag_param=0.15 srf_ex_cnv_gust=.true. [namelist:jules_surface_types] @@ -734,7 +758,7 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [namelist:microphysics] @@ -912,16 +936,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 microphysics_placement='slow' orographic_drag_placement='slow' radiation_placement='slow' @@ -931,7 +956,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1345,6 +1370,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.true. adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.true. ageofair_reset_level=10 broken_w2_projection=.false. diff --git a/rose-stem/app/lfric_coupled/file/mydef.xml b/rose-stem/app/lfric_coupled/file/mydef.xml index 6a8237962..807535157 100644 --- a/rose-stem/app/lfric_coupled/file/mydef.xml +++ b/rose-stem/app/lfric_coupled/file/mydef.xml @@ -140,6 +140,18 @@ + + + + + + + + + + + + @@ -453,7 +465,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_coupled_atmosphere/file/iodef_basic_gal.xml b/rose-stem/app/lfric_coupled_atmosphere/file/iodef_basic_gal.xml index 648c09acc..a98e7aa5a 100644 --- a/rose-stem/app/lfric_coupled_atmosphere/file/iodef_basic_gal.xml +++ b/rose-stem/app/lfric_coupled_atmosphere/file/iodef_basic_gal.xml @@ -1163,7 +1163,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/lfric_coupled_atmosphere/rose-app.conf b/rose-stem/app/lfric_coupled_atmosphere/rose-app.conf index ce50c6fa3..8edd951c1 100644 --- a/rose-stem/app/lfric_coupled_atmosphere/rose-app.conf +++ b/rose-stem/app/lfric_coupled_atmosphere/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-lfric_atm/vn3.0 +meta=lfric-lfric_atm/vn3.1 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -47,6 +47,7 @@ source=(namelist:aerosol) = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -281,6 +282,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=0 [namelist:damping_layer] @@ -607,6 +609,9 @@ write_minmax_tseries=.false. l_hydrology=.true. l_var_rainfrac=.true. +[namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -690,14 +695,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +beta_cnv_bl=0.04 cor_mo_iter='improved' +fd_hill_option='capped_lowhill' fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +orog_drag_param=0.15 srf_ex_cnv_gust=.true. [namelist:jules_surface_types] @@ -729,7 +753,7 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [namelist:microphysics] @@ -902,16 +926,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 microphysics_placement='slow' orographic_drag_placement='slow' radiation_placement='slow' @@ -921,7 +946,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1335,6 +1360,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.true. calculate_detj='upwind' diff --git a/rose-stem/app/linear_model/file/field_def_diags_ls.xml b/rose-stem/app/linear_model/file/field_def_diags_ls.xml new file mode 100644 index 000000000..8a2c34e54 --- /dev/null +++ b/rose-stem/app/linear_model/file/field_def_diags_ls.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/file_def_ancil.xml b/rose-stem/app/linear_model/file/file_def_ancil.xml new file mode 100644 index 000000000..43c9e9e44 --- /dev/null +++ b/rose-stem/app/linear_model/file/file_def_ancil.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/file_def_check_restart.xml b/rose-stem/app/linear_model/file/file_def_check_restart.xml new file mode 100644 index 000000000..05ba6dcbc --- /dev/null +++ b/rose-stem/app/linear_model/file/file_def_check_restart.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/file_def_diags.xml b/rose-stem/app/linear_model/file/file_def_diags.xml new file mode 100644 index 000000000..c12613f00 --- /dev/null +++ b/rose-stem/app/linear_model/file/file_def_diags.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/file_def_diags_ls.xml b/rose-stem/app/linear_model/file/file_def_diags_ls.xml new file mode 100644 index 000000000..0cdd03798 --- /dev/null +++ b/rose-stem/app/linear_model/file/file_def_diags_ls.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/file_def_initial.xml b/rose-stem/app/linear_model/file/file_def_initial.xml new file mode 100644 index 000000000..05a68968e --- /dev/null +++ b/rose-stem/app/linear_model/file/file_def_initial.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/file_def_ls.xml b/rose-stem/app/linear_model/file/file_def_ls.xml new file mode 100644 index 000000000..a2766a236 --- /dev/null +++ b/rose-stem/app/linear_model/file/file_def_ls.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/file_def_read.xml b/rose-stem/app/linear_model/file/file_def_read.xml new file mode 100644 index 000000000..61cc7f81e --- /dev/null +++ b/rose-stem/app/linear_model/file/file_def_read.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/rose-stem/app/linear_model/file/iodef.xml b/rose-stem/app/linear_model/file/iodef.xml index 8591084dc..fb000671f 100644 --- a/rose-stem/app/linear_model/file/iodef.xml +++ b/rose-stem/app/linear_model/file/iodef.xml @@ -5,331 +5,59 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - processed__tot_col_uv_kinetic_energy + processed__tot_col_w_kinetic_energy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -337,7 +65,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf index 01576bf19..8bf78b63c 100644 --- a/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf +++ b/rose-stem/app/linear_model/opt/rose-app-dcmip301.conf @@ -62,6 +62,17 @@ fixed_ls=.false. l_stabilise_bl=.false. pert_option='analytic' +[namelist:linear_physics] +!!blevs_m=15 +!!e_folding_levs_m=10 +!!l_0_m=80.0 +l_boundary_layer=.false. +!!log_layer=2 +!!u_land_m=0.4 +!!u_sea_m=0.4 +!!z_land_m=0.05 +!!z_sea_m=0.0005 + [!!namelist:multigrid] chain_mesh_tags='','','','' diff --git a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf index 4b375741d..864c6a623 100644 --- a/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf +++ b/rose-stem/app/linear_model/opt/rose-app-nwp_gal9_c12.conf @@ -3,8 +3,8 @@ mode=auto source=$ROSE_SUITE_DIR/app/linear_model/file/iodef.xml [namelist:files] -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' -ls_filename='final_ls' +ls_directory='$BIG_DATA_DIR/tangent-linear/PullRequest182' +ls_filename='final_ls_with_land' start_dump_directory='$BIG_DATA_DIR/tangent-linear/Ticket354' start_dump_filename='final_pert' diff --git a/rose-stem/app/linear_model/opt/rose-app-runge-kutta.conf b/rose-stem/app/linear_model/opt/rose-app-runge-kutta.conf index 1047582b2..6daa69cf5 100644 --- a/rose-stem/app/linear_model/opt/rose-app-runge-kutta.conf +++ b/rose-stem/app/linear_model/opt/rose-app-runge-kutta.conf @@ -63,6 +63,17 @@ fixed_ls=.false. l_stabilise_bl=.false. pert_option='analytic' +[namelist:linear_physics] +!!blevs_m=15 +!!e_folding_levs_m=10 +!!l_0_m=80.0 +l_boundary_layer=.false. +!!log_layer=2 +!!u_land_m=0.4 +!!u_sea_m=0.4 +!!z_land_m=0.05 +!!z_sea_m=0.0005 + [namelist:mixed_solver] gcrk=6 mixed_solver_a_tol=1.0e-6 @@ -98,4 +109,6 @@ cfl_mol_2d_stab=2.0 cfl_mol_3d_stab=2.0 max_vert_cfl_calc='uniform' runge_kutta_method='ssp4' +scheme=5*1 +splitting=5*1 !!wind_mono_top_depth=0 diff --git a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf index be23c9c84..14de51a9a 100644 --- a/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf +++ b/rose-stem/app/linear_model/opt/rose-app-semi-implicit.conf @@ -61,6 +61,17 @@ diagnostic_frequency=20 l_stabilise_bl=.false. pert_option='analytic' +[namelist:linear_physics] +!!blevs_m=15 +!!e_folding_levs_m=10 +!!l_0_m=80.0 +l_boundary_layer=.false. +!!log_layer=2 +!!u_land_m=0.4 +!!u_sea_m=0.4 +!!z_land_m=0.05 +!!z_sea_m=0.0005 + [namelist:mixed_solver] gcrk=6 mixed_solver_a_tol=1.0e-6 @@ -86,4 +97,6 @@ inner_iterations=2 tau_u=0.5 [namelist:transport] +scheme=5*1 +splitting=5*1 !!wind_mono_top_depth=0 diff --git a/rose-stem/app/linear_model/rose-app.conf b/rose-stem/app/linear_model/rose-app.conf index 1c83c6635..47f8bacb6 100644 --- a/rose-stem/app/linear_model/rose-app.conf +++ b/rose-stem/app/linear_model/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-linear_model/vn3.0 +meta=lfric-linear_model/vn3.0_t108 [command] default=rose env-cat iodef_temp.xml -o iodef.xml; $LAUNCH_SCRIPT/launch-exe @@ -50,6 +50,7 @@ source=(namelist:aerosol) = (namelist:initial_wind) = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -61,6 +62,7 @@ source=(namelist:aerosol) = (namelist:jules_urban) = (namelist:jules_vegetation) = namelist:linear + = namelist:linear_physics = namelist:logging = (namelist:microphysics) = namelist:mixed_solver @@ -271,6 +273,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [namelist:damping_layer] @@ -376,7 +379,7 @@ diag_stem_name='diagGungho' !!land_area_ancil_path='' !!lbc_directory='' !!lbc_filename='' -ls_directory='$BIG_DATA_DIR/tangent-linear/Ticket735' +ls_directory='$BIG_DATA_DIR/tangent-linear/PullRequest182' ls_filename='final_2021060200-2021060207' !!no3_ancil_path='' !!o3_ancil_path='' @@ -597,6 +600,9 @@ write_minmax_tseries=.false. l_hydrology=.true. !!l_var_rainfrac=.true. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -680,14 +686,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='improved' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.true. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -720,14 +745,26 @@ l_spec_veg_z0=.true. [namelist:linear] fixed_ls=.true. -l_stabilise_bl=.true. +l_stabilise_bl=.false. ls_read_w2h=.false. max_bl_stabilisation=0.75 n_bl_levels_to_stabilise=15 pert_option='file' +transport_efficiency=.true. + +[namelist:linear_physics] +blevs_m=15 +e_folding_levs_m=10 +l_0_m=80.0 +l_boundary_layer=.true. +log_layer=2 +u_land_m=0.4 +u_sea_m=0.4 +z_land_m=0.05 +z_sea_m=0.0005 [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -905,16 +942,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -924,7 +962,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1338,6 +1376,7 @@ tau_u=0.55 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=30000.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. ageofair_reset_level=10 broken_w2_projection=.false. @@ -1376,11 +1415,11 @@ panel_edge_treatment='none' profile_size=5 reversible=.true.,.true.,.false.,.true.,.true. runge_kutta_method='ssp3' -scheme=5*1 +scheme=5*3 si_outer_transport='none' slice_order='parabola' special_edges_monotone=5*1 -splitting=5*1 +splitting=5*2 substep_transport='off' theta_dispersion_correction=.false. theta_variable='dry' diff --git a/rose-stem/app/memory_profile/bin/plot_memory_ex1a.py b/rose-stem/app/memory_profile/bin/plot_memory_ex1a.py index c3cf079ef..3011dd57c 100755 --- a/rose-stem/app/memory_profile/bin/plot_memory_ex1a.py +++ b/rose-stem/app/memory_profile/bin/plot_memory_ex1a.py @@ -84,6 +84,11 @@ def plot_run_job(run, out_filename): if matcher: mpiprocs = int(matcher.group(2)) + if not os.path.exists(os.path.join(run, 'job.out')): + time.sleep(5) + if not os.path.exists(os.path.join(run, 'job.out')): + raise FileNotFoundError(f'{run}/job.out does not exist') + with open(os.path.join(run, 'job.out'), encoding="utf-8") as jof: jofr = jof.read() # re pattern to find max memory usage report by node @@ -99,8 +104,8 @@ def plot_run_job(run, out_filename): raise ValueError('Failed to parse memory per node from job.out. ' 'Check that the PBS script has run and output ' 'and that both MEMORY_PROFILE is true & ' - 'TARGET_PLATFORM = "meto-ex1a" in the environment ' - 'variables passed to launch-exe.') + 'TARGET_PLATFORM = "meto-ex1a" in the ' + 'environment variables passed to launch-exe.') run_env_vars = {} # parse environment variables from job.out @@ -127,14 +132,15 @@ def plot_run_job(run, out_filename): if wclock_rep.match(jofr) is not None: wclock, = wclock_rep.findall(jofr) if wclock == "missing": - #wclock = "missing" + # wclock = "missing" # 2025-06-04T13:50:31Z INFO - started # 2025-06-04T14:48:33Z INFO - succeeded start_pattern = re.compile(r'([0-9\-:T]+)Z INFO - started') astart, = start_pattern.findall(jofr) success_pattern = re.compile(r'([0-9\-:T]+)Z INFO - succeeded') asuccess, = success_pattern.findall(jofr) - wt = datetime.datetime.fromisoformat(asuccess)-datetime.datetime.fromisoformat(astart) + wt = datetime.datetime.fromisoformat(asuccess) \ + - datetime.datetime.fromisoformat(astart) wclock = str(wt) if mpiprocs is not None: @@ -158,7 +164,8 @@ def plot_run_job(run, out_filename): run_stats['run'][f"{run_env_vars.get('EXEC_NAME', '')} ranks"] = tranks run_stats['run']['OMP_threads'] = run_env_vars.get('OMP_NUM_THREADS', '') if run_env_vars.get('XIOS_SERVER_MODE') == 'True': - run_stats['run']['xios_server ranks'] = int(run_env_vars.get('XIOS_SERVER_RANKS', '')) + run_stats['run']['xios_server ranks'] = \ + int(run_env_vars.get('XIOS_SERVER_RANKS', '')) # Run configuration information is now encoded into the title to be used # for plotting. # Next, parse run configuration information from the job.err PBS file; @@ -168,7 +175,7 @@ def plot_run_job(run, out_filename): jefr = jef.read() # re pattern for max_mem_{process} for mem per rank mem_per_rank_rep = re.compile('(([a-z]+[0-9]+) ([0-9]+): ' - 'max_mem_([a-zA-Z_]+)_([0-9]+)kb)+') + 'max_mem_([a-zA-Z0-9_]+)_([0-9]+)kb)+') mem_per_rank = mem_per_rank_rep.findall(jefr) mem_per_rank.sort(key=lambda x: (x[1], int(x[2]))) mem_per_rank = [{'node': m[1], 'rank': int(m[2]), 'exec': m[3], @@ -205,8 +212,8 @@ def plot_run_job(run, out_filename): # Assign a label and colour, then plot this element as a stacked bar # updating the stacking container and adding labels. # handle minimal legend for multi-bar stack with these flags - lfirst=True - xfirst=True + lfirst = True + xfirst = True lfh = None xfh = None for m in mem_per_rank: @@ -214,13 +221,14 @@ def plot_run_job(run, out_filename): col = "black" xval = nodes.index(m['node']) y = m['memkB']*KB_TO_MIB - if m['exec'] == 'lfric' or m['exec'] == 'lfric_atm': - label = 'lfric_atm' + if m['exec'] == 'lfric' or m['exec'] == 'lfric_atm' or \ + m['exec'] == 'lfric2um' or m['exec'] == 'um2lfric': + label = m['exec'] col = 'green' if lfirst: lfirst = False - lfh = ax.bar(xval, y, width=width, bottom=bottom[xval], color=col, - label=label, edgecolor='black') + lfh = ax.bar(xval, y, width=width, bottom=bottom[xval], + color=col, label=label, edgecolor='black') else: ax.bar(xval, y, width=width, bottom=bottom[xval], color=col, label=label, edgecolor='black') @@ -229,8 +237,8 @@ def plot_run_job(run, out_filename): col = 'blue' if xfirst: xfirst = False - xfh = ax.bar(xval, y, width=width, bottom=bottom[xval], color=col, - label=label, edgecolor='black') + xfh = ax.bar(xval, y, width=width, bottom=bottom[xval], + color=col, label=label, edgecolor='black') else: ax.bar(xval, y, width=width, bottom=bottom[xval], color=col, label=label, edgecolor='black') @@ -245,7 +253,8 @@ def plot_run_job(run, out_filename): # Calculate summary statistics to append to the title. all_lf = [m['memkB']*KB_TO_MIB for m in mem_per_rank - if m['exec'] == 'lfric_atm' or m['exec'] == 'lfric'] + if m['exec'] == 'lfric_atm' or m['exec'] == 'lfric' or + m['exec'] == 'lfric2um' or m['exec'] == 'um2lfric'] all_x = [m['memkB']*KB_TO_MIB for m in mem_per_rank if m['exec'] == 'xios_server' or m['exec'] == 'xios'] all_n = [int(int(m['memMiB'])/1024) for m in mem_per_node] @@ -256,10 +265,12 @@ def plot_run_job(run, out_filename): f'≤ {int(max(all_lf))}') run_stats[run_env_vars.get('EXEC_NAME', '')] = {} - run_stats[run_env_vars.get('EXEC_NAME', '')]['mean'] = statistics.mean(all_lf) + run_stats[run_env_vars.get('EXEC_NAME', '')]['mean'] = \ + statistics.mean(all_lf) run_stats[run_env_vars.get('EXEC_NAME', '')]['max'] = max(all_lf) run_stats[run_env_vars.get('EXEC_NAME', '')]['min'] = min(all_lf) - run_stats[run_env_vars.get('EXEC_NAME', '')]['std_dev'] = statistics.stdev(all_lf) + run_stats[run_env_vars.get('EXEC_NAME', '')]['std_dev'] = \ + statistics.stdev(all_lf) run_stats[run_env_vars.get('EXEC_NAME', '')]['units'] = 'max mem MiB' if all_x: tstats = tstats + (f'\n{int(min(all_x))} ≤ xios_server (max mem MiB): ' @@ -302,6 +313,7 @@ def plot_run_job(run, out_filename): with open(out_filename + '.json', 'w', encoding="utf-8") as jsonout: jsonout.write(json.dumps(run_stats)) + if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("run_job") diff --git a/rose-stem/app/mesh/opt/rose-app-C12_MG_op.conf b/rose-stem/app/mesh/opt/rose-app-C12_MG_op.conf new file mode 100644 index 000000000..cf587eab3 --- /dev/null +++ b/rose-stem/app/mesh/opt/rose-app-C12_MG_op.conf @@ -0,0 +1,18 @@ +[command] +default=mkdir -p $MESH_DIR ; mpiexec -n 1 $BIN_DIR/cubedsphere_mesh_generator mesh_generation.nml +srun=mkdir -p $MESH_DIR ; srun --ntasks=1 $BIN_DIR/cubedsphere_mesh_generator mesh_generation.nml + +[namelist:cubedsphere_mesh] +edge_cells=12,6,3 + +[namelist:mesh] +mesh_maps='dynamics:multigrid_l1','multigrid_l1:multigrid_l2' +mesh_names='dynamics','multigrid_l1','multigrid_l2' +n_meshes=3 +partition_mesh=.true. + +[namelist:partitions] +generate_inner_halos=.true. +max_stencil_depth=2 +n_partitions=6 +partition_range=0,5 diff --git a/rose-stem/app/mesh/opt/rose-app-C24_MG_op.conf b/rose-stem/app/mesh/opt/rose-app-C24_MG_op.conf index 8637bea24..01e28da75 100644 --- a/rose-stem/app/mesh/opt/rose-app-C24_MG_op.conf +++ b/rose-stem/app/mesh/opt/rose-app-C24_MG_op.conf @@ -1,5 +1,6 @@ [command] default=mkdir -p $MESH_DIR ; mpiexec -n 1 $BIN_DIR/cubedsphere_mesh_generator mesh_generation.nml +srun=mkdir -p $MESH_DIR ; srun --ntasks=1 $BIN_DIR/cubedsphere_mesh_generator mesh_generation.nml [namelist:cubedsphere_mesh] edge_cells=24,12,6,3 diff --git a/rose-stem/app/mesh/opt/rose-app-ral3_seuk.conf b/rose-stem/app/mesh/opt/rose-app-ral3_seuk.conf index c246b5d54..fcb7c2c22 100644 --- a/rose-stem/app/mesh/opt/rose-app-ral3_seuk.conf +++ b/rose-stem/app/mesh/opt/rose-app-ral3_seuk.conf @@ -4,215 +4,16 @@ default=mkdir -p $MESH_DIR ; mpiexec -n 1 $BIN_DIR/planar_mesh_generator mesh_ge [env] mesh_generator=Planar -[namelist:aerosol] -aclw_file='lut/nml_ac_lw' -acsw_file='lut/nml_ac_sw' -activation_scheme='off' -anlw_file='lut/nml_an_lw' -answ_file='lut/nml_an_sw' -crlw_file='lut/nml_cr_lw' -crsw_file='lut/nml_cr_sw' -l_radaer=.true. -n_radaer_step=1 -prec_file='precalc/RADAER_pcalc.ukca' -sulphuric_strat_column=1.86604e-6 - -[namelist:blayer] -bl_levels=69 -bl_mix_w=.true. -free_atm_mix='free_trop_layer' -interp_local='gradients' -noice_in_turb=.true. -p_unstable=0.5 -relax_sc_over_cu=.true. -sbl_opt='sharpest' -sg_orog_mixing='shear_plus_lambda' - -[namelist:boundaries] -blend_frequency='inner' -blending_weights=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1 -lbc_eos_height=38 -lbc_method='onion_layer' -limited_area=.true. -normal_only=.true. -output_lbcs=.true. -solver_boundary_depth=4 -transport_boundary_depth=4 - -[namelist:chemistry] - -[namelist:cloud] -cld_fsd_hill=.false. -cloud_horizontal_fsd=0.65 -ez_subcrit=.false. -ice_width=0.02 -rh_crit=0.960,0.940,0.920,0.900,0.890,0.880,0.870,0.860,0.850,0.840, - =0.840,0.830,0.820,0.810,56*0.800 -rh_crit_opt='namelist' -scheme='bimodal' -subgrid_qv=.false. -use_fsd_eff_res=.false. - -[namelist:convection] -cape_timescale=1800.0 -cv_scheme='gregory_rowntree' -number_of_convection_substeps=2 - [!!namelist:cubedsphere_mesh] -[namelist:damping_layer] -dl_base=30000.0 - -[namelist:extrusion] -domain_top=40000.0 -method='um_L70_61t_9s_40km' -stretching_height=16641.984 - -[namelist:files] -ancil_directory='$BIG_DATA_DIR/ancils/proto-ral/Ticket3510/seuk' -hydtop_ancil_path='hydrol_lsh/hydrosheds/qrparm.hydtop.ugrid' -land_area_ancil_path='land_sea_mask/qrparm.mask.ugrid.fixed' -lbc_directory='$BIG_DATA_DIR/lbcs/proto-ral/Ticket3510/seuk' -lbc_filename='checkpoint_um2lfric_000001_fixedtime_date' -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' -orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' -ozone_ancil_path='ozone/sparc/1994-2005/qrclim.ozone_L70_O70.ugrid' -plant_func_ancil_path='qrparm.veg.func.ugrid' -sea_ancil_path='general_sea/GlobColour/qrclim.sea.ugrid' -sea_ice_ancil_path='seaice/hadisst_6190/v4/qrclim.seaice.ugrid' -soil_ancil_path='qrparm.soil_cci.ugrid' -soil_rough_ancil_path='soil_roughness/prigent12/qrparm.soil_roughness' -sst_ancil_path='sst/hadisst_6190/v1/qrclim.sst.ugrid' -start_dump_directory='$BIG_DATA_DIR/start_dumps/proto-ral/Ticket3510/seuk' -start_dump_filename='checkpoint_um2lfric_000001' -surface_frac_ancil_path='qrparm.veg.frac.ugrid' - -[namelist:finite_element] -coord_order=2 -coord_system='xyz' - -[namelist:formulation] -shallow=.false. - -[namelist:initialization] -lbc_option='um2lfric_file' -model_eos_height=38 -read_w2h_wind=.true. -sst_source='start_dump' - -[namelist:jules_nvegparm] -albsnc_nvg_io=0.4,0.06,0.8,0.8 -albsnf_nvg_io=0.18,0.06,-1.0,0.75 -ch_nvg_io=2.8e5,4.18e6,0.0,0.0 - -[namelist:jules_snow] -rho_snow_fresh=170.0 - -[namelist:jules_surface] -l_vary_z0m_soil=.false. - [namelist:mesh] mesh_maps='dynamics:multigrid_l1' mesh_names='dynamics','multigrid_l1' n_meshes=2 topology='non_periodic' -[namelist:microphysics] -droplet_tpr=.true. -fcrit=1.0 -graupel_scheme='modified' -microphysics_casim=.true. -ndrop_surf=10.0e6 -nscalesf=1.0 -nsigmasf=2.82843 -orog_block=.false. -orog_rain=.false. -orog_rime=.false. -prog_tnuc=.false. -shape_rime=.true. -turb_gen_mixph=.false. -z_surf=50.0 - -[namelist:mixed_solver] -fail_on_non_converged=.false. -monitor_convergence=.false. -si_method='prec_only' - -[namelist:mixing] -leonard_kl=2.0 -leonard_term=.true. -method='blend_1dbl_fa' -mix_factor=0.2 -smagorinsky=.true. - -[namelist:multigrid] -n_postsmooth=6 - -[namelist:orographic_drag] - -[namelist:orography] -orog_init_option='start_dump' - -[namelist:partitioning] -partitioner='planar' - -[namelist:physics] -convection_placement='fast' -electric_placement='slow' -orographic_drag_placement='slow' -smagorinsky_placement='fast' -spectral_gwd_placement='slow' - [namelist:planar_mesh] edge_cells_x=32,64 edge_cells_y=32,64 periodic_x=.false. periodic_y=.false. - -[namelist:radiation] -cloud_inhomogeneity='scaling' -cloud_overlap='maximum_random' -cloud_representation='liquid_and_ice' -cloud_vertical_decorr=10000.0 -i_cloud_ice_type_lwinc=11 -i_cloud_ice_type_swinc=11 -i_cloud_liq_type_lwinc=5 -i_cloud_liq_type_swinc=5 -l_inc_radstep=.true. -liu_aparam=0.07 -liu_bparam=-0.14 -n_horiz_ang=16 -n_horiz_layer=1 -n_inc_radstep=5 -n_radstep=15 -scatter_method_lwinc='approx' -spectral_file_lw='spec/sp_lw_ga7' -spectral_file_lwinc='spec/sp_lw_cloud7' -spectral_file_sw='spec/sp_sw_ga7' -spectral_file_swinc='spec/sp_sw_cloud7' -topography='horizon' - -[namelist:section_choice] -aerosol='none' -chemistry='none' -convection='none' -electric='um' -methane_oxidation=.false. -orographic_drag='none' -spectral_gwd='none' - -[namelist:spectral_gwd] -cgw_scale_factor=1.05 - -[namelist:surface] -alb_snocov_max=1.5e-1,1.5e-1,6.0e-1,6.0e-1,4.0e-1 -buddy_sea='Off' -z0hm_ratio_pft=1.00,1.00,0.022,0.022,0.025 -z0v=1.1,1.1,0.1,0.1,0.4 - -[namelist:time] -calendar_origin='2021-07-29 00:00:00' -calendar_start='2021-07-29 00:00:00' - -[namelist:transport] -extended_mesh=.false. diff --git a/rose-stem/app/mesh/opt/rose-app-ral3_uk.conf b/rose-stem/app/mesh/opt/rose-app-ral3_uk.conf index daf0db140..fcb7c2c22 100644 --- a/rose-stem/app/mesh/opt/rose-app-ral3_uk.conf +++ b/rose-stem/app/mesh/opt/rose-app-ral3_uk.conf @@ -4,210 +4,16 @@ default=mkdir -p $MESH_DIR ; mpiexec -n 1 $BIN_DIR/planar_mesh_generator mesh_ge [env] mesh_generator=Planar -[namelist:aerosol] -activation_scheme='off' -glomap_mode='climatology' -n_radaer_step=4 - -[namelist:blayer] -bl_levels=69 -bl_mix_w=.true. -free_atm_mix='free_trop_layer' -interp_local='gradients' -noice_in_turb=.true. -p_unstable=0.5 -relax_sc_over_cu=.true. -sbl_opt='sharpest' -sg_orog_mixing='shear_plus_lambda' - -[namelist:boundaries] -blend_frequency='inner' -blending_weights=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1 -lbc_eos_height=10 -lbc_method='onion_layer' -limited_area=.true. -normal_only=.true. -output_lbcs=.true. -solver_boundary_depth=4 -transport_boundary_depth=4 - -[namelist:chemistry] - -[namelist:cloud] -cld_fsd_hill=.false. -cloud_horizontal_fsd=0.65 -ez_subcrit=.false. -ice_width=0.02 -rh_crit=0.960,0.940,0.920,0.900,0.890,0.880,0.870,0.860,0.850,0.840, - =0.840,0.830,0.820,0.810,56*0.800 -rh_crit_opt='namelist' -scheme='bimodal' -subgrid_qv=.false. -use_fsd_eff_res=.false. - -[namelist:convection] -cape_timescale=1800.0 -cv_scheme='gregory_rowntree' -number_of_convection_substeps=2 - [!!namelist:cubedsphere_mesh] -[namelist:damping_layer] -dl_base=30000.0 - -[namelist:extrusion] -domain_top=40000.0 -method='um_L70_61t_9s_40km' -stretching_height=16641.984 - -[namelist:files] -aerosols_ancil_path='aerosol_clims/glomap/glomap_clim_n48_v2.ugrid' -ancil_directory='$BIG_DATA_DIR/ancils/proto-ral/Ticket3510/uk' -hydtop_ancil_path='hydrol_lsh/hydrosheds/qrparm.hydtop.ugrid' -land_area_ancil_path='land_sea_mask/qrparm.mask.ugrid.fixed' -lbc_directory='$BIG_DATA_DIR/lbcs/proto-ral/Ticket3510/uk_new' -lbc_filename='lbc_fixedtime_000' -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' -orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog.ugrid' -ozone_ancil_path='ozone/sparc/1994-2005/qrclim.ozone_L70_O70.ugrid' -plant_func_ancil_path='qrparm.veg.func.ugrid' -sea_ancil_path='general_sea/GlobColour/qrclim.sea.ugrid' -sea_ice_ancil_path='seaice/hadisst_6190/v4/qrclim.seaice.ugrid' -soil_ancil_path='qrparm.soil_cci.ugrid' -soil_rough_ancil_path='soil_roughness/prigent12/qrparm.soil_roughness' -sst_ancil_path='sst/hadisst_6190/v1/qrclim.sst.ugrid' -start_dump_directory='$BIG_DATA_DIR/start_dumps/proto-ral/Ticket3510/uk_new' -start_dump_filename='checkpoint_um2lfric_000001' -surface_frac_ancil_path='qrparm.veg.frac.ugrid' - -[namelist:finite_element] -coord_order=2 -coord_system='xyz' - -[namelist:formulation] -shallow=.false. - -[namelist:initialization] -lbc_option='um2lfric_file' -model_eos_height=38 -read_w2h_wind=.true. -sst_source='start_dump' - -[namelist:jules_nvegparm] -albsnc_nvg_io=0.4,0.06,0.8,0.8 -albsnf_nvg_io=0.18,0.06,-1.0,0.75 -ch_nvg_io=2.8e5,4.18e6,0.0,0.0 - -[namelist:jules_snow] -rho_snow_fresh=170.0 - -[namelist:jules_surface] -l_vary_z0m_soil=.false. - [namelist:mesh] mesh_maps='dynamics:multigrid_l1' mesh_names='dynamics','multigrid_l1' n_meshes=2 topology='non_periodic' -[namelist:microphysics] -droplet_tpr=.true. -fcrit=1.0 -graupel_scheme='modified' -microphysics_casim=.true. -ndrop_surf=10.0e6 -nscalesf=1.0 -nsigmasf=2.82843 -orog_block=.false. -orog_rain=.false. -orog_rime=.false. -prog_tnuc=.false. -shape_rime=.true. -turb_gen_mixph=.false. -z_surf=50.0 - -[namelist:mixed_solver] -fail_on_non_converged=.false. -monitor_convergence=.false. -si_method='prec_only' - -[namelist:mixing] -leonard_kl=2.0 -leonard_term=.true. -method='blend_1dbl_fa' -mix_factor=0.2 -smagorinsky=.true. - -[namelist:multigrid] -n_postsmooth=6 - -[namelist:orographic_drag] - -[namelist:orography] -orog_init_option='start_dump' - -[namelist:partitioning] -partitioner='planar' - -[namelist:physics] -convection_placement='fast' -electric_placement='slow' -orographic_drag_placement='slow' -smagorinsky_placement='fast' -spectral_gwd_placement='slow' - [namelist:planar_mesh] edge_cells_x=32,64 edge_cells_y=32,64 periodic_x=.false. periodic_y=.false. - -[namelist:radiation] -cloud_inhomogeneity='scaling' -cloud_overlap='maximum_random' -cloud_representation='liquid_and_ice' -cloud_vertical_decorr=10000.0 -i_cloud_ice_type_lwinc=11 -i_cloud_ice_type_swinc=11 -i_cloud_liq_type_lwinc=5 -i_cloud_liq_type_swinc=5 -l_inc_radstep=.true. -liu_aparam=0.07 -liu_bparam=-0.14 -n_horiz_ang=16 -n_horiz_layer=1 -n_inc_radstep=5 -n_radstep=15 -scatter_method_lwinc='approx' -spectral_file_lw='spec/sp_lw_ga7' -spectral_file_lwinc='spec/sp_lw_cloud7' -spectral_file_sw='spec/sp_sw_ga7' -spectral_file_swinc='spec/sp_sw_cloud7' -topography='horizon' - -[namelist:section_choice] -chemistry='none' -convection='none' -electric='um' -methane_oxidation=.false. -orographic_drag='none' -spectral_gwd='none' - -[namelist:spectral_gwd] -cgw_scale_factor=1.05 - -[namelist:subgrid] -dep_pt_stencil_extent=5 - -[namelist:surface] -alb_snocov_max=1.5e-1,1.5e-1,6.0e-1,6.0e-1,4.0e-1 -buddy_sea='Off' -z0hm_ratio_pft=1.00,1.00,0.022,0.022,0.025 -z0v=1.1,1.1,0.1,0.1,0.4 - -[namelist:time] -calendar_origin='2021-07-29 00:00:00' -calendar_start='2021-07-29 00:00:00' - -[namelist:transport] -extended_mesh=.false. diff --git a/rose-stem/app/mesh/opt/rose-app-ral3_ukv.conf b/rose-stem/app/mesh/opt/rose-app-ral3_ukv.conf index 557ac431f..fcb7c2c22 100644 --- a/rose-stem/app/mesh/opt/rose-app-ral3_ukv.conf +++ b/rose-stem/app/mesh/opt/rose-app-ral3_ukv.conf @@ -4,210 +4,16 @@ default=mkdir -p $MESH_DIR ; mpiexec -n 1 $BIN_DIR/planar_mesh_generator mesh_ge [env] mesh_generator=Planar -[namelist:aerosol] -activation_scheme='off' -glomap_mode='climatology' -n_radaer_step=4 - -[namelist:blayer] -bl_levels=69 -bl_mix_w=.true. -free_atm_mix='free_trop_layer' -interp_local='gradients' -noice_in_turb=.true. -p_unstable=0.5 -relax_sc_over_cu=.true. -sbl_opt='sharpest' -sg_orog_mixing='shear_plus_lambda' - -[namelist:boundaries] -blend_frequency='inner' -blending_weights=1.0,1.0,1.0,1.0,0.9,0.7,0.5,0.3,0.1 -lbc_eos_height=10 -lbc_method='onion_layer' -limited_area=.true. -normal_only=.true. -output_lbcs=.true. -solver_boundary_depth=4 -transport_boundary_depth=4 - -[namelist:chemistry] - -[namelist:cloud] -cld_fsd_hill=.false. -cloud_horizontal_fsd=0.65 -ez_subcrit=.false. -ice_width=0.02 -rh_crit=0.960,0.940,0.920,0.900,0.890,0.880,0.870,0.860,0.850,0.840, - =0.840,0.830,0.820,0.810,56*0.800 -rh_crit_opt='namelist' -scheme='bimodal' -subgrid_qv=.false. -use_fsd_eff_res=.false. - -[namelist:convection] -cape_timescale=1800.0 -cv_scheme='gregory_rowntree' -number_of_convection_substeps=2 - [!!namelist:cubedsphere_mesh] -[namelist:damping_layer] -dl_base=30000.0 - -[namelist:extrusion] -domain_top=40000.0 -method='um_L70_61t_9s_40km' -stretching_height=16641.984 - -[namelist:files] -aerosols_ancil_path='aerosol_clims/glomap/glomap_clim_n48_v2.ugrid' -ancil_directory='$BIG_DATA_DIR/ancils/proto-ral/Ticket4248/var_uk' -hydtop_ancil_path='hydrol_lsh/hydrosheds/qrparm.hydtop.ugrid' -land_area_ancil_path='land_sea_mask/qrparm.mask.ugrid.fixed' -lbc_directory='$BIG_DATA_DIR/lbcs/proto-ral/Ticket4248/var_uk' -lbc_filename='lbc_fixedtime_000' -orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog_horizon.ugrid' -orography_subgrid_ancil_path='orography/gmted_ramp2/qrparm.orog_horizon.ugrid' -ozone_ancil_path='ozone/sparc/1994-2005/qrclim.ozone_L70_O70.ugrid' -plant_func_ancil_path='qrparm.veg.func.ugrid' -sea_ancil_path='general_sea/GlobColour/qrclim.sea.ugrid' -sea_ice_ancil_path='seaice/hadisst_6190/v4/qrclim.seaice.ugrid' -soil_ancil_path='qrparm.soil_cci.ugrid' -soil_rough_ancil_path='soil_roughness/prigent12/qrparm.soil_roughness' -sst_ancil_path='sst/hadisst_6190/v1/qrclim.sst.ugrid' -start_dump_directory='$BIG_DATA_DIR/start_dumps/proto-ral/Ticket4248/var_uk' -start_dump_filename='checkpoint_um2lfric_000001' -surface_frac_ancil_path='qrparm.veg.frac.ugrid' - -[namelist:finite_element] -coord_order=2 -coord_system='xyz' - -[namelist:formulation] -shallow=.false. - -[namelist:initialization] -lbc_option='um2lfric_file' -model_eos_height=38 -read_w2h_wind=.true. -sst_source='start_dump' - -[namelist:jules_nvegparm] -albsnc_nvg_io=0.4,0.06,0.8,0.8 -albsnf_nvg_io=0.18,0.06,-1.0,0.75 -ch_nvg_io=2.8e5,4.18e6,0.0,0.0 - -[namelist:jules_snow] -rho_snow_fresh=170.0 - -[namelist:jules_surface] -l_vary_z0m_soil=.false. - [namelist:mesh] mesh_maps='dynamics:multigrid_l1' mesh_names='dynamics','multigrid_l1' n_meshes=2 topology='non_periodic' -[namelist:microphysics] -droplet_tpr=.true. -fcrit=1.0 -graupel_scheme='modified' -microphysics_casim=.true. -ndrop_surf=10.0e6 -nscalesf=1.0 -nsigmasf=2.82843 -orog_block=.false. -orog_rain=.false. -orog_rime=.false. -prog_tnuc=.false. -shape_rime=.true. -turb_gen_mixph=.false. -z_surf=50.0 - -[namelist:mixed_solver] -fail_on_non_converged=.false. -monitor_convergence=.false. -si_method='prec_only' - -[namelist:mixing] -leonard_kl=2.0 -leonard_term=.true. -method='blend_1dbl_fa' -mix_factor=0.2 -smagorinsky=.true. - -[namelist:multigrid] -n_postsmooth=6 - -[namelist:orographic_drag] - -[namelist:orography] -orog_init_option='start_dump' - -[namelist:partitioning] -partitioner='planar' - -[namelist:physics] -convection_placement='fast' -electric_placement='slow' -orographic_drag_placement='slow' -smagorinsky_placement='fast' -spectral_gwd_placement='slow' - [namelist:planar_mesh] edge_cells_x=32,64 edge_cells_y=32,64 periodic_x=.false. periodic_y=.false. - -[namelist:radiation] -cloud_inhomogeneity='scaling' -cloud_overlap='maximum_random' -cloud_representation='liquid_and_ice' -cloud_vertical_decorr=10000.0 -i_cloud_ice_type_lwinc=11 -i_cloud_ice_type_swinc=11 -i_cloud_liq_type_lwinc=5 -i_cloud_liq_type_swinc=5 -l_inc_radstep=.true. -liu_aparam=0.07 -liu_bparam=-0.14 -n_horiz_ang=16 -n_horiz_layer=1 -n_inc_radstep=5 -n_radstep=15 -scatter_method_lwinc='approx' -spectral_file_lw='spec/sp_lw_ga7' -spectral_file_lwinc='spec/sp_lw_cloud7' -spectral_file_sw='spec/sp_sw_ga7' -spectral_file_swinc='spec/sp_sw_cloud7' -topography='horizon' - -[namelist:section_choice] -chemistry='none' -convection='none' -electric='um' -methane_oxidation=.false. -orographic_drag='none' -spectral_gwd='none' - -[namelist:spectral_gwd] -cgw_scale_factor=1.05 - -[namelist:subgrid] -dep_pt_stencil_extent=5 - -[namelist:surface] -alb_snocov_max=1.5e-1,1.5e-1,6.0e-1,6.0e-1,4.0e-1 -buddy_sea='Off' -z0hm_ratio_pft=1.00,1.00,0.022,0.022,0.025 -z0v=1.1,1.1,0.1,0.1,0.4 - -[namelist:time] -calendar_origin='2021-07-29 00:00:00' -calendar_start='2021-07-29 00:00:00' - -[namelist:transport] -extended_mesh=.false. diff --git a/rose-stem/app/mesh/opt/rose-app-seuk_MG.conf b/rose-stem/app/mesh/opt/rose-app-seuk_MG.conf index 3ac0ca473..311c21616 100644 --- a/rose-stem/app/mesh/opt/rose-app-seuk_MG.conf +++ b/rose-stem/app/mesh/opt/rose-app-seuk_MG.conf @@ -15,10 +15,13 @@ rotate_mesh=.true. topology='non_periodic' [namelist:planar_mesh] +create_lbc_mesh=.true. domain_centre=1.69,-0.97 domain_size=1.28,0.96 edge_cells_x=64,32,16,8 edge_cells_y=64,32,16,8 +lbc_parent_mesh='dynamics' +lbc_rim_depth=4 periodic_x=.false. periodic_y=.false. diff --git a/rose-stem/app/mesh/rose-app.conf b/rose-stem/app/mesh/rose-app.conf index e34b44b7e..7d0e7538e 100644 --- a/rose-stem/app/mesh/rose-app.conf +++ b/rose-stem/app/mesh/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-mesh_tools/vn3.0 +meta=lfric-mesh_tools/vn3.1 [command] default=echo "There is no default mesh generator, please specify an optional configuration"; false diff --git a/rose-stem/app/name_transport/file/iodef.xml b/rose-stem/app/name_transport/file/iodef.xml index 721c1582c..a7328f5be 100644 --- a/rose-stem/app/name_transport/file/iodef.xml +++ b/rose-stem/app/name_transport/file/iodef.xml @@ -107,7 +107,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/name_transport/rose-app.conf b/rose-stem/app/name_transport/rose-app.conf index 81070757a..1112eb2e7 100644 --- a/rose-stem/app/name_transport/rose-app.conf +++ b/rose-stem/app/name_transport/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-name_transport/vn3.0 +meta=lfric-name_transport/vn3.1 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -31,6 +31,7 @@ source=namelist:base_mesh = namelist:initialization = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -240,6 +241,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [!!namelist:damping_layer] @@ -576,6 +578,9 @@ write_minmax_tseries=.false. l_hydrology=.true. !!l_var_rainfrac=.false. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -659,14 +664,33 @@ l_soil_sat_down=.true. l_vg_soil=.true. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='lim_oblen' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -698,7 +722,7 @@ l_limit_canhc=.false. l_spec_veg_z0=.false. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -875,16 +899,17 @@ panel_decomposition='auto' partitioner='planar' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 !!limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -894,7 +919,7 @@ configure_segments=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1308,6 +1333,7 @@ tau_u=0.5 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj='upwind' diff --git a/rose-stem/app/ngarch/file/iodef.xml b/rose-stem/app/ngarch/file/iodef.xml index 1c3923716..bc54bb678 100644 --- a/rose-stem/app/ngarch/file/iodef.xml +++ b/rose-stem/app/ngarch/file/iodef.xml @@ -104,7 +104,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/ngarch/rose-app.conf b/rose-stem/app/ngarch/rose-app.conf index 0652790e8..bc6cfdb63 100644 --- a/rose-stem/app/ngarch/rose-app.conf +++ b/rose-stem/app/ngarch/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-ngarch/vn3.0 +meta=lfric-ngarch/vn3.1 [command] default=$CORE_ROOT_DIR/bin/tweak_iodef; \ @@ -49,6 +49,7 @@ source=namelist:base_mesh = namelist:initial_wind = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -269,6 +270,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [!!namelist:damping_layer] @@ -642,6 +644,9 @@ write_minmax_tseries=.false. l_hydrology=.true. l_var_rainfrac=.true. +[namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -725,14 +730,33 @@ l_soil_sat_down=.true. l_vg_soil=.false. [namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +beta_cnv_bl=0.04 cor_mo_iter='improved' +fd_hill_option='capped_lowhill' fd_stability_dep='none' formdrag='dist_drag' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.true. +orog_drag_param=0.15 srf_ex_cnv_gust=.true. [namelist:jules_surface_types] @@ -764,7 +788,7 @@ l_limit_canhc=.true. l_spec_veg_z0=.true. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [namelist:microphysics] @@ -937,16 +961,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 limit_drag_incs=.false. lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -956,7 +981,7 @@ sample_physics_winds_correction=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1388,6 +1413,7 @@ tau_u=0.5 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. ageofair_reset_level=10 broken_w2_projection=.false. diff --git a/rose-stem/app/plot/bin/baroclinic.py b/rose-stem/app/plot/bin/baroclinic.py index 305454901..92237a945 100755 --- a/rose-stem/app/plot/bin/baroclinic.py +++ b/rose-stem/app/plot/bin/baroclinic.py @@ -88,7 +88,8 @@ def make_figures(filein, plotpath, fields, vertical_spacing, formulation): else: combined_fields = [field] - interp_fig = plt.figure(figsize=(20, 10)) + interp_fig, ax = plt.subplots(figsize=(20, 10)) + for cfield in combined_fields: cube = read_ugrid_data(filein, cfield) @@ -166,63 +167,55 @@ def make_figures(filein, plotpath, fields, vertical_spacing, formulation): kappa = rd/1005.0 plot_data[:, :, level] = 0.01*fi**(1.0/kappa) * p0 - nplots = 1 - nxplots = 1 - nyplots = 1 - - for iplot in range(nplots): - ax = interp_fig.add_subplot(nxplots, nyplots, iplot+1) - level = iplot - if (cfield == 'm_v' or cfield == 'm_cl'): - # Plot level 10 for mositure fields - level = 10 - cmap = magma.reversed() + if (cfield == 'm_v' or cfield == 'm_cl'): + # Plot level 10 for moisture fields + level = 10 + cmap = magma.reversed() + else: + level = 0 + cmap = magma + + if direction == 'xz': + lon, height = np.meshgrid(xi, zi) + CS = ax.contourf(lon, height, + plot_data[:, plot_lat, :].T, + levels=levels, cmap=cmap) + plt.colorbar(cmap=cmap) + CL = ax.contour(lat, height, + plot_data[:, plot_lat, :].T, + levels=levels, linewidths=0.5, + colors='k') + ax.title(['lat = ', yi[plot_lat]*360./np.real(nx)]) + if direction == 'yz': + lat, height = np.meshgrid(yi, zi) + CS = ax.contourf(lat, height, + plot_data[:, plot_long, :].T, + levels=levels, cmap=cmap) + ax.colorbar(cmap=cmap) + CL = ax.contour(lat, height, + plot_data[:, plot_long, :].T, + levels=levels, linewidths=0.5, + colors='k') + ax.title(['long = ', xi[plot_long]*360./np.real(nx)]) + if direction == 'xy': + lat, lon = np.meshgrid(yi, xi) + if cfield == 'exner': + # Extrapolate data to the surface + dz = plot_data[:, :, 0] + (zi_f[0] - zi_h[0]) * \ + (plot_data[:, :, 0] - plot_data[:, :, level]) \ + / (zi_h[0] - zi_h[1]) else: - cmap = magma - ys = np.tile(yi, (n_levs, 1)) - - - if direction == 'xz': - lon, height = np.meshgrid(xi, zi) - CS = plt.contourf(lon, height, - plot_data[:, plot_lat, :].T, - levels=levels, cmap=cmap) - plt.colorbar(cmap=cmap) - CL = plt.contour(lat, height, - plot_data[:, plot_lat, :].T, - levels=levels, linewidths=0.5, - colors='k') - plt.title(['lat = ', yi[plot_lat]*360./np.real(nx)]) - if direction == 'yz': - lat, height = np.meshgrid(yi, zi) - CS = plt.contourf(lat, height, - plot_data[:, plot_long, :].T, - levels=levels, cmap=cmap) - plt.colorbar(cmap=cmap) - CL = plt.contour(lat, height, - plot_data[:, plot_long, :].T, - levels=levels, linewidths=0.5, - colors='k') - plt.title(['long = ', xi[plot_long]*360./np.real(nx)]) - if direction == 'xy': - lat, lon = np.meshgrid(yi, xi) - if cfield == 'exner' and iplot == 0: - # Extrapolate data to the surface - dz = plot_data[:, :, 0] + (zi_f[0] - zi_h[0]) * \ - (plot_data[:, :, 0] - plot_data[:, :, level]) \ - / (zi_h[0] - zi_h[1]) - else: - dz = plot_data[:, :, level] - if cfield != 'exner': - CS = plt.contourf(lon, lat, - plot_data[:, :, level].T, - levels=levels, cmap=cmap) - plt.colorbar(cmap=cmap) - if cfield != 'theta': - CL = plt.contour(lon, lat, dz.T, levels=levels, - linewidths=1.0, colors='k') - plt.clabel(CL, CL.levels[1::2], fontsize=15, - inline=1, fmt='%3.1f') + dz = plot_data[:, :, level] + if cfield != 'exner': + CS = ax.contourf(lon, lat, + plot_data[:, :, level].T, + levels=levels, cmap=cmap) + _ = interp_fig.colorbar(CS, ax=ax) + if cfield != 'theta': + CL = ax.contour(lon, lat, dz.T, levels=levels, + linewidths=1.0, colors='k') + ax.clabel(CL, CL.levels[1::2], fontsize=15, + inline=1, fmt='%3.1f') pngfile = '%s/baroclinic_plot-%s-time%s-%s.png' % \ (plotpath, cfield, time[t], direction) diff --git a/rose-stem/app/plot/bin/straka_plot_x.py b/rose-stem/app/plot/bin/straka_plot_x.py index a50fafc3d..d6f355aa5 100755 --- a/rose-stem/app/plot/bin/straka_plot_x.py +++ b/rose-stem/app/plot/bin/straka_plot_x.py @@ -54,7 +54,7 @@ def make_figure(plotpath, nx, ny, field, component, timestep): val_col = 'c' + str(component) - slice_fig = plt.figure(figsize=(15, 10)) + slice_fig, ax = plt.subplots(figsize=(12, 5)) # get min and max of x,y data for plot axes min_lev = min(levels) @@ -99,18 +99,22 @@ def make_figure(plotpath, nx, ny, field, component, timestep): for i in range(nx): dz[i, :] = zi[0, i, :] - back - matplotlib.rcParams['contour.negative_linestyle'] = 'solid' - cf = plt.contourf(x_i * r2d, y_i * r2d, np.round(dz, 10), - cc, cmap=c_map, extend='min') - plt.axes().set_aspect(.8) - plt.axis([0, 16, 0, 5]) - plt.xlabel("x (km)", fontsize=28) - plt.ylabel("z (km)", fontsize=28) - cb = plt.colorbar(cf, cmap=c_map, fraction=0.011, pad=0.04) + cf = ax.contourf(x_i * r2d, y_i * r2d, np.round(dz, 10), + cc, cmap=c_map, extend='min') + # Add contour lines -- solid for negative + _ = ax.contour(x_i * r2d, y_i * r2d, np.round(dz, 10), cc, + colors='k', linewidths=0.5, linestyles='solid') + + ax.set_xlabel("x (km)", fontsize=28) + ax.set_ylabel("z (km)", fontsize=28) + ax.set_xlim([0.0, 16.0]) + ax.set_ylim([0.0, 5.0]) + ax.set_xticks(np.arange(0, 18, 2)) + ax.set_yticks(np.arange(0, 6, 1)) + # Set tick label size + ax.tick_params(axis='both', which='major', labelsize=24) + cb = plt.colorbar(cf, cmap=c_map, pad=0.04) cb.ax.tick_params(labelsize=24) - plt.xticks(np.arange(0, 18, 2)) - plt.yticks(np.arange(0, 6, 1)) - plt.tick_params(axis='both', labelsize=28) # Front position is symmetrized print(nx, np.min(dz), np.max(dz)) diff --git a/rose-stem/app/scintelapi/file/iodef.xml b/rose-stem/app/scintelapi/file/iodef.xml index 8b6a2101e..9c0ec56e2 100644 --- a/rose-stem/app/scintelapi/file/iodef.xml +++ b/rose-stem/app/scintelapi/file/iodef.xml @@ -88,7 +88,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/scintelapi/file/iodef_basic.xml b/rose-stem/app/scintelapi/file/iodef_basic.xml index 4ff96e195..18c8cc1ed 100644 --- a/rose-stem/app/scintelapi/file/iodef_basic.xml +++ b/rose-stem/app/scintelapi/file/iodef_basic.xml @@ -89,7 +89,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/scintelapi/file/iodef_mixingratio.xml b/rose-stem/app/scintelapi/file/iodef_mixingratio.xml index efbaa0c99..a853623e7 100644 --- a/rose-stem/app/scintelapi/file/iodef_mixingratio.xml +++ b/rose-stem/app/scintelapi/file/iodef_mixingratio.xml @@ -67,7 +67,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/shallow_water/file/iodef.xml b/rose-stem/app/shallow_water/file/iodef.xml index 5b41c7bb5..e25596689 100644 --- a/rose-stem/app/shallow_water/file/iodef.xml +++ b/rose-stem/app/shallow_water/file/iodef.xml @@ -157,7 +157,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/shallow_water/rose-app.conf b/rose-stem/app/shallow_water/rose-app.conf index 4925a58af..4180237d9 100644 --- a/rose-stem/app/shallow_water/rose-app.conf +++ b/rose-stem/app/shallow_water/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-shallow_water/vn3.0 +meta=lfric-shallow_water/vn3.1 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -32,6 +32,7 @@ source=namelist:base_mesh = namelist:idealised = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -235,6 +236,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [!!namelist:damping_layer] @@ -561,6 +563,9 @@ write_minmax_tseries=.false. l_hydrology=.true. !!l_var_rainfrac=.false. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -644,14 +649,33 @@ l_soil_sat_down=.true. l_vg_soil=.true. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='lim_oblen' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -683,7 +707,7 @@ l_limit_canhc=.false. l_spec_veg_z0=.false. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -848,16 +872,17 @@ panel_decomposition='auto' partitioner='cubedsphere' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 !!limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -867,7 +892,7 @@ configure_segments=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1297,6 +1322,7 @@ tau_u=0.0 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.true. calculate_detj='upwind' diff --git a/rose-stem/app/solver/rose-app.conf b/rose-stem/app/solver/rose-app.conf index 51300e343..ea2ecba84 100644 --- a/rose-stem/app/solver/rose-app.conf +++ b/rose-stem/app/solver/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-solver/vn3.0 +meta=lfric-solver/vn3.1 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -58,7 +58,7 @@ l_multigrid=.false. use_multires_coupling=.false. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:multigrid] diff --git a/rose-stem/app/test_launch-exe/bin/test_launch_exe_configuration_meto.py b/rose-stem/app/test_launch-exe/bin/test_launch_exe_configuration_meto.py index d77f3275f..39c20b8fb 100755 --- a/rose-stem/app/test_launch-exe/bin/test_launch_exe_configuration_meto.py +++ b/rose-stem/app/test_launch-exe/bin/test_launch_exe_configuration_meto.py @@ -157,7 +157,7 @@ def test_run_lfric_atm_scm_ral3_urban2t_BiP2x2_50000x50000_azspice_gnu_fast_debu capture_output=True) assert sr.returncode == 0, sr.stderr.decode("UTF-8") - def test_run_lfric_atm_nwp_gal9_mgnoukca_C48_MG_ex1a_cce_fast_debug_64bit(self, monkeypatch): + def test_run_lfric_atm_nwp_gal9_mg_C48_MG_ex1a_cce_fast_debug_64bit(self, monkeypatch): monkeypatch.setenv("TARGET_PLATFORM", "meto-ex1a") monkeypatch.setenv("RUN_METHOD", "mpiexec") monkeypatch.setenv("HYPERTHREADS", "1") @@ -637,7 +637,7 @@ def test_run_lfric_atm_nwp_gal9_C224_MG_ex1a_cce_fast_debug_64bit_rbl32(self, mo monkeypatch.setenv("BIN_DIR", "$OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32") monkeypatch.setenv("EXEC_NAME", "lfric_atm") monkeypatch.setenv("PAT_EXE_EXTEN", "") - monkeypatch.setenv("TEST_LAUNCH_EXE_EXEC", "mpiexec --cpu-bind=depth --np 1176 --depth 1 --ppn 128 $OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32/lfric_atm configuration.nml : --cpu-bind=depth --np 16 --ppn 4 xios_server.exe") + monkeypatch.setenv("TEST_LAUNCH_EXE_EXEC", "mpiexec --cpu-bind=depth --np 1176 --depth 1 --ppn 128 $OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32/lfric_atm configuration.nml : --cpu-bind=depth --np 16 --depth 32 --ppn 4 xios_server.exe") sr = subprocess.run(self.launch_exe, capture_output=True) assert sr.returncode == 0, sr.stderr.decode("UTF-8") @@ -659,7 +659,7 @@ def test_run_mem_profile_lfric_atm_nwp_gal9_C224_MG_ex1a_cce_fast_debug_64bit_rb monkeypatch.setenv("EXEC_NAME", "lfric_atm") monkeypatch.setenv("PAT_EXE_EXTEN", "") monkeypatch.setenv("MEMORY_PROFILE", "True") - monkeypatch.setenv("TEST_LAUNCH_EXE_EXEC", "mpiexec --line-buffer --label --cpu-bind=depth --np 1176 --depth 1 --ppn 128 /usr/bin/time -f max_mem_lfric_atm_%Mkb $OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32/lfric_atm configuration.nml : --cpu-bind=depth --np 16 --ppn 4 /usr/bin/time -f max_mem_xios_server_%Mkb xios_server.exe") + monkeypatch.setenv("TEST_LAUNCH_EXE_EXEC", "mpiexec --line-buffer --label --cpu-bind=depth --np 1176 --depth 1 --ppn 128 /usr/bin/time -f max_mem_lfric_atm_%Mkb $OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32/lfric_atm configuration.nml : --cpu-bind=depth --np 16 --depth 32 --ppn 4 /usr/bin/time -f max_mem_xios_server_%Mkb xios_server.exe") sr = subprocess.run(self.launch_exe, capture_output=True) assert sr.returncode == 0, sr.stderr.decode("UTF-8") @@ -681,7 +681,28 @@ def test_run_mem_profile_false_lfric_atm_nwp_gal9_C224_MG_ex1a_cce_fast_debug_64 monkeypatch.setenv("EXEC_NAME", "lfric_atm") monkeypatch.setenv("PAT_EXE_EXTEN", "") monkeypatch.setenv("MEMORY_PROFILE", "False") - monkeypatch.setenv("TEST_LAUNCH_EXE_EXEC", "mpiexec --cpu-bind=depth --np 1176 --depth 1 --ppn 128 $OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32/lfric_atm configuration.nml : --cpu-bind=depth --np 16 --ppn 4 xios_server.exe") + monkeypatch.setenv("TEST_LAUNCH_EXE_EXEC", "mpiexec --cpu-bind=depth --np 1176 --depth 1 --ppn 128 $OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32/lfric_atm configuration.nml : --cpu-bind=depth --np 16 --depth 32 --ppn 4 xios_server.exe") + sr = subprocess.run(self.launch_exe, + capture_output=True) + assert sr.returncode == 0, sr.stderr.decode("UTF-8") + + def test_run_lfric_atm_nwp_gal9_C896_MG_ex1a_cce_production_32bit(self, monkeypatch): + monkeypatch.setenv("TARGET_PLATFORM", "meto-ex1a") + monkeypatch.setenv("RUN_METHOD", "mpiexec") + monkeypatch.setenv("HYPERTHREADS", "1") + monkeypatch.setenv("CORES_PER_NODE", "128") + monkeypatch.setenv("NUMA_REGIONS_PER_NODE", "2") + monkeypatch.setenv("OMP_NUM_THREADS", "1") + monkeypatch.setenv("TOTAL_RANKS", "4704") + monkeypatch.setenv("XIOS_SERVER_MODE", "True") + monkeypatch.setenv("XIOS_SERVER_RANKS", "128") + monkeypatch.setenv("xios_nodes", "4") + monkeypatch.setenv("mpi_parts_xios", "128") + monkeypatch.setenv("CORES_PER_NODE_OVERRIDE", "0") + monkeypatch.setenv("BIN_DIR", "$OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32") + monkeypatch.setenv("EXEC_NAME", "lfric_atm") + monkeypatch.setenv("PAT_EXE_EXTEN", "") + monkeypatch.setenv("TEST_LAUNCH_EXE_EXEC", "mpiexec --cpu-bind=depth --np 4704 --depth 1 --ppn 128 $OUTPUT_ROOT/bin/lfric_atm/cce_fast-debug-64bit-rbl32/lfric_atm configuration.nml : --cpu-bind=depth --np 128 --depth 4 --ppn 32 xios_server.exe") sr = subprocess.run(self.launch_exe, capture_output=True) assert sr.returncode == 0, sr.stderr.decode("UTF-8") diff --git a/rose-stem/app/transport/file/iodef.xml b/rose-stem/app/transport/file/iodef.xml index b09d984f5..19554bb49 100644 --- a/rose-stem/app/transport/file/iodef.xml +++ b/rose-stem/app/transport/file/iodef.xml @@ -189,7 +189,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/transport/file/iodef_coarse_aero.xml b/rose-stem/app/transport/file/iodef_coarse_aero.xml index 69802ca32..90d33e368 100644 --- a/rose-stem/app/transport/file/iodef_coarse_aero.xml +++ b/rose-stem/app/transport/file/iodef_coarse_aero.xml @@ -207,7 +207,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/transport/rose-app.conf b/rose-stem/app/transport/rose-app.conf index b5a4cd880..085ddc4c0 100644 --- a/rose-stem/app/transport/rose-app.conf +++ b/rose-stem/app/transport/rose-app.conf @@ -1,4 +1,4 @@ -meta=lfric-transport/vn3.0 +meta=lfric-transport/vn3.1 [command] default=$LAUNCH_SCRIPT/launch-exe @@ -31,6 +31,7 @@ source=namelist:base_mesh = namelist:initialization = namelist:io = (namelist:jules_hydrology) + = (namelist:jules_model_environment_lfric) = (namelist:jules_nvegparm) = (namelist:jules_pftparm) = (namelist:jules_radiation) @@ -239,6 +240,7 @@ resdep_precipramp=.false. [namelist:cosp] l_cosp=.false. +!!n_cosp_step=1 !!n_subcol_gen=64 [!!namelist:damping_layer] @@ -575,6 +577,9 @@ write_minmax_tseries=.false. l_hydrology=.true. !!l_var_rainfrac=.false. +[!!namelist:jules_model_environment_lfric] +l_jules_parent='lfric' + [!!namelist:jules_nvegparm] albsnc_nvg_io=0.4,0.8,0.8,0.8 albsnf_nvg_io=0.18,0.12,-1.0,0.75 @@ -658,14 +663,33 @@ l_soil_sat_down=.true. l_vg_soil=.true. [!!namelist:jules_surface] +all_tiles='off' !!anthrop_heat_mean=20.0 !!anthrop_heat_option='dukes' +beta1=0.83 +beta2=0.93 +!!beta_cnv_bl=0.04 cor_mo_iter='lim_oblen' +!!fd_hill_option='capped_lowhill' !!fd_stability_dep='none' formdrag='none' +fwe_c3=0.5 +fwe_c4=20000.0 +hleaf=5.7e4 +hwood=1.1e4 +i_modiscopt='on' +iscrntdiag='decoupled_trans' l_anthrop_heat_src=.false. +!!l_elev_land_ice=.false. +!!l_elev_lw_down=.false. +l_epot_corr=.true. +!!l_flake_model=.false. +l_land_ice_imp=.true. +l_mo_buoyancy_calc=.true. +!!l_point_data=.false. l_urban2t=.false. l_vary_z0m_soil=.false. +!!orog_drag_param=0.15 srf_ex_cnv_gust=.true. [!!namelist:jules_surface_types] @@ -697,7 +721,7 @@ l_limit_canhc=.false. l_spec_veg_z0=.false. [namelist:logging] -log_to_rank_zero_only=.false. +log_to_rank_zero_only=.true. run_log_level='info' [!!namelist:microphysics] @@ -871,16 +895,17 @@ panel_decomposition='auto' partitioner='planar' [namelist:physics] -!!bl_segment=0 +bl_segment=0 !!blayer_placement='fast' -configure_segments=.false. +configure_segments=.true. +conv_gr_segment=16 !!convection_placement='fast' !!electric_placement='slow' !!evap_condense_placement='fast' -!!gw_segment=0 +gw_segment=0 !!limit_drag_incs=.false. !!lowest_level='gradient' -!!ls_ppn_segment=0 +ls_ppn_segment=0 !!microphysics_placement='slow' !!orographic_drag_placement='slow' !!radiation_placement='slow' @@ -890,7 +915,7 @@ configure_segments=.false. !!smagorinsky_placement='end' !!spectral_gwd_placement='slow' !!stochastic_physics_placement='fast' -!!ussp_segment=0 +ussp_segment=0 [namelist:planet] cp=1005.0 @@ -1304,6 +1329,7 @@ tau_u=0.5 [namelist:transport] adjust_theta=.false. !!adjust_theta_above=0.0 +adjust_tracer_equation=.false. adjust_vhv_wind=.false. broken_w2_projection=.false. calculate_detj='upwind' diff --git a/rose-stem/app/um2lfric/file/iodef_aquaplanet_lam_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_aquaplanet_lam_stash_list.xml index 74a776bf7..2d87a42e7 100644 --- a/rose-stem/app/um2lfric/file/iodef_aquaplanet_lam_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_aquaplanet_lam_stash_list.xml @@ -135,7 +135,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/um2lfric/file/iodef_aquaplanet_lbc_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_aquaplanet_lbc_stash_list.xml index 1e3db353c..73560214c 100644 --- a/rose-stem/app/um2lfric/file/iodef_aquaplanet_lbc_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_aquaplanet_lbc_stash_list.xml @@ -88,7 +88,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/um2lfric/file/iodef_aquaplanet_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_aquaplanet_stash_list.xml index 0e8060797..2c83ecd8d 100644 --- a/rose-stem/app/um2lfric/file/iodef_aquaplanet_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_aquaplanet_stash_list.xml @@ -137,7 +137,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/um2lfric/file/iodef_basicgal_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_basicgal_stash_list.xml index a98dfb39f..b3618b94f 100644 --- a/rose-stem/app/um2lfric/file/iodef_basicgal_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_basicgal_stash_list.xml @@ -164,7 +164,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/um2lfric/file/iodef_falklands_lam_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_falklands_lam_stash_list.xml index 84ba1b565..c7bb9306c 100644 --- a/rose-stem/app/um2lfric/file/iodef_falklands_lam_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_falklands_lam_stash_list.xml @@ -171,7 +171,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/um2lfric/file/iodef_nwp_gal9_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_nwp_gal9_stash_list.xml index e4e40424d..68787eee8 100644 --- a/rose-stem/app/um2lfric/file/iodef_nwp_gal9_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_nwp_gal9_stash_list.xml @@ -176,7 +176,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/um2lfric/file/iodef_protogal_chem_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_protogal_chem_stash_list.xml index f1d88af7d..7990b0677 100644 --- a/rose-stem/app/um2lfric/file/iodef_protogal_chem_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_protogal_chem_stash_list.xml @@ -432,7 +432,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/app/um2lfric/file/iodef_protogal_stash_list.xml b/rose-stem/app/um2lfric/file/iodef_protogal_stash_list.xml index 06fd81acd..294b86c17 100644 --- a/rose-stem/app/um2lfric/file/iodef_protogal_stash_list.xml +++ b/rose-stem/app/um2lfric/file/iodef_protogal_stash_list.xml @@ -204,7 +204,7 @@ performance - 1.0 + 1.0 diff --git a/rose-stem/bin/application_results_setup.sh b/rose-stem/bin/application_results_setup.sh index 7363fd63d..4ed4e8a15 100755 --- a/rose-stem/bin/application_results_setup.sh +++ b/rose-stem/bin/application_results_setup.sh @@ -8,18 +8,16 @@ # Prepare results location mkdir -p $TASK_OUTPUT_DIR/results/ +# Symbolic link to results directory, so all files can write to /work/results/ +ln -sf $TASK_OUTPUT_DIR/results $CYLC_TASK_WORK_DIR/results +# Specific results directory symbolic link exceptions to support +# `lfric_diag.nc`, `lfric_averages.nc` & `lfric_initial` across many tests +# In general output files should target `name="results/fname"` in XIOS xml +ln -sf $TASK_OUTPUT_DIR/results/lfric_diag.nc $CYLC_TASK_WORK_DIR/lfric_diag.nc +ln -sf $TASK_OUTPUT_DIR/results/lfric_averages.nc $CYLC_TASK_WORK_DIR/lfric_averages.nc +ln -sf $TASK_OUTPUT_DIR/results/lfric_initial.nc $CYLC_TASK_WORK_DIR/lfric_initial.nc if [ $LUSTRE_FILESYSTEM ]; then # Set Lustre striping to maximum for results (performance) - lfs setstripe -c -1 $TASK_OUTPUT_DIR/results/ + lfs setstripe -c 32 -S 4m -p flash $TASK_OUTPUT_DIR/results/ + lfs setstripe -c 32 -S 4m -p flash $CYLC_SUITE_SHARE_DIR/data/ fi - -# Symbolic link for each potential output file, -# from `work` to `results` -# avoiding cp copy commands, as these are very -# storage & wall clock intensive -ln -sf $TASK_OUTPUT_DIR/results/lfric_diagnostics.nc $CYLC_TASK_WORK_DIR/lfric_diagnostics.nc -ln -sf $TASK_OUTPUT_DIR/results/lfric_diag.nc $CYLC_TASK_WORK_DIR/lfric_diag.nc -ln -sf $TASK_OUTPUT_DIR/results/lfric_ver.nc $CYLC_TASK_WORK_DIR/lfric_ver.nc -ln -sf $TASK_OUTPUT_DIR/results/lfric_ver_tp0.nc $CYLC_TASK_WORK_DIR/lfric_ver_tp0.nc -ln -sf $TASK_OUTPUT_DIR/results/lfric_initial.nc $CYLC_TASK_WORK_DIR/lfric_initial.nc -ln -sf $TASK_OUTPUT_DIR/results/lfric_averages.nc $CYLC_TASK_WORK_DIR/lfric_averages.nc diff --git a/rose-stem/rose-suite.conf b/rose-stem/rose-suite.conf index c720c8bc7..932fb2d2c 100644 --- a/rose-stem/rose-suite.conf +++ b/rose-stem/rose-suite.conf @@ -6,4 +6,4 @@ OVERRIDE_LOG_LEVEL='' USE_HEADS=false USE_MIRRORS=false USE_TOKENS=false -VN='3.0' +VN='3.1' diff --git a/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc b/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc index 6a32d88bf..a76f3d572 100644 --- a/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc +++ b/rose-stem/site/common/adjoint_tests/tasks_adjoint_tests.cylc @@ -5,18 +5,24 @@ {# ########################################################################### #} {% do LOG.debug("Entered site/common/adjoint_tests/tasks_adjoint_tests.cylc") %} -{% if task_ns.conf_name == "default-C12" %} +{% if task_ns.conf_name == "nwp_gal9-C12_MG" %} {% do task_dict.update({ - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "strict_solver", "rrt_equals_dt"], + "resolution": "C12_MG", + "DT": 1800, + "tsteps": 12, + "log_level": "debug", }) %} -{% elif task_ns.conf_name == "varying_ls-C12" %} +{% elif task_ns.conf_name == "nwp_gal9-C12_MG-varying_LS" %} {% do task_dict.update({ - "opt_confs": ["varying_ls"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "strict_solver", "rrt_equals_dt", "varying_ls"], + "resolution": "C12_MG", + "DT": 1800, + "tsteps": 12, + "log_level": "debug", }) %} {% elif task_ns.conf_name == "canned" %} @@ -45,4 +51,4 @@ {% endif %} {% endif %} -{% do LOG.debug("Finished in site/common/adjoint_tests/tasks_jedi_lfric_tests.cylc") %} +{% do LOG.debug("Finished in site/common/adjoint_tests/tasks_adjoint_tests.cylc") %} diff --git a/rose-stem/site/common/gungho_model/tasks_gungho_model.cylc b/rose-stem/site/common/gungho_model/tasks_gungho_model.cylc index 17c6843c5..727dfdfd9 100644 --- a/rose-stem/site/common/gungho_model/tasks_gungho_model.cylc +++ b/rose-stem/site/common/gungho_model/tasks_gungho_model.cylc @@ -34,6 +34,47 @@ "plot_str": "baroclinic.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR dcmip dry surface_pressure_temperature", }) %} +{% elif task_ns.conf_name == "baroclinic-C48_MG" %} + + {% do task_dict.update({ + "opt_confs": ["baroclinic"], + "resolution": "C48_MG", + "DT": 3600, + "threads": 4, + "mpi_parts": 6, + "tsteps": 240, + "plot_str": "baroclinic.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR dcmip dry surface_pressure_temperature", + }) %} +{% elif task_ns.conf_name == "baroclinic-C48_MG-3panel" %} + + {% do task_dict.update({ + "opt_confs": ["baroclinic"], + "resolution": "C48_MG", + "DT": 3600, + "threads": 1, + "mpi_parts": 12, + "panel_decomp": "custom", + "xproc": 2, + "yproc": 3, + "tsteps": 240, + "plot_str": "baroclinic.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR dcmip dry surface_pressure_temperature", + }) %} + +{% elif task_ns.conf_name == "baroclinic-C48_MG-2panel" %} + + {% do task_dict.update({ + "opt_confs": ["baroclinic"], + "resolution": "C48_MG", + "DT": 3600, + "threads": 1, + "mpi_parts": 27, + "panel_decomp": "custom", + "xproc": 3, + "yproc": 3, + "tsteps": 240, + "plot_str": "baroclinic.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR dcmip dry surface_pressure_temperature", + }) %} + {% elif task_ns.conf_name == "baroclinic-pert-C24_MG" %} {% do task_dict.update({ diff --git a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc index 22c3c0742..25cf5232d 100644 --- a/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc +++ b/rose-stem/site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc @@ -5,12 +5,11 @@ {# ########################################################################### #} {% do LOG.debug("Entered site/common/jedi_lfric_tests/tasks_jedi_lfric_tests.cylc") %} -{% if task_ns.conf_name == "nwp_gal9-C12" %} +{% if task_ns.conf_name == "nwp_gal9-C12_MG" %} {% do task_dict.update({ - "opt_confs": ["nwp_gal9"], - "resolution": "C12", - "ancil_resolution": "C12", + "opt_confs": ["nwp_gal9_c12"], + "resolution": "C12_MG", "DT": 1800, "tsteps": 12, "mpi_parts": 6, @@ -21,7 +20,7 @@ {% do task_dict.update({ "opt_confs": ["runge-kutta"], "resolution": "C12", - "ancil_resolution": "C12", + "DT": 1, "tsteps": 20, }) %} @@ -61,181 +60,226 @@ "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_forecast_tl_default-C12" %} +{% elif task_ns.conf_name == "tlm_forecast_tl_nwp_gal9-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_forecast_tl", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "id_tlm_tests_default-C12" %} +{% elif task_ns.conf_name == "id_tlm_tests_nwp_gal9-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_id_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "id_tlm_tests_default-1PE-C12" %} +{% elif task_ns.conf_name == "id_tlm_tests_nwp_gal9-1PE-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_id_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-1PE-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-1PE-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-1PE-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "real_increment"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, + "tsteps": 13, + "mpi_parts": 6, + "threads": 4, + }) %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-1PE-4OMP-C12_MG" %} + + {% do task_dict.update({ + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG", + "ancil_resolution": "C12", + "DT": 1800, "tsteps": 13, "mpi_parts": 1, "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-1PE-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-1PE-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-dry-1PE-4OMP-C12" %} +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "dry"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver", "dry"], + "resolution": "C12_MG", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 1, "threads": 4, }) %} - -{% elif task_ns.conf_name == "tlm_tests_default-relaxed_solver-C12" %} +{% elif task_ns.conf_name == "tlm_forecast_tl_nwp_gal9-C12_MG_op" %} {% do task_dict.update({ - "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "relaxed_solver"], - "resolution": "C12", + "app_name": "jedi_tlm_forecast_tl", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG_op", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-relaxed_solver-1PE-C12" %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-C12_MG_op" %} {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default", "relaxed_solver"], - "resolution": "C12", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C12_MG_op", "ancil_resolution": "C12", - "DT": 3600, + "DT": 1800, "tsteps": 13, - "mpi_parts": 1, + "mpi_parts": 6, }) %} -{% elif task_ns.conf_name == "tlm_forecast_tl_default-C12_op" %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG" %} + {% do task_dict.update({ - "app_name": "jedi_tlm_forecast_tl", - "opt_confs": ["default"], - "resolution": "C12_op", + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c12", "rrt_equals_dt", "strict_solver"], + "resolution": "C12_MG", "ancil_resolution": "C12", "DT": 1800, "tsteps": 13, "mpi_parts": 6, + "threads": 4, + }) %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-4OMP-C224_MG" %} + + {% do task_dict.update({ + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "semi_strict_solver"], + "resolution": "C224_MG", + "ancil_resolution": "C224", + "DT": 1800, + "tsteps": 13, + "mpi_parts": 1176, + "threads": 4, }) %} -{% elif task_ns.conf_name == "tlm_tests_default-C12_op" %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-real_increment-4OMP-C224_MG" %} + {% do task_dict.update({ "app_name": "jedi_tlm_tests", - "opt_confs": ["default"], - "resolution": "C12_op", - "ancil_resolution": "C12", - "DT": 3600, + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "real_increment", "semi_strict_solver"], + "resolution": "C224_MG", + "ancil_resolution": "C224", + "DT": 1800, "tsteps": 13, - "mpi_parts": 6, + "mpi_parts": 1176, + "threads": 4, + }) %} + +{% elif task_ns.conf_name == "tlm_tests_nwp_gal9-strict_solver-4OMP-C224_MG" %} + + {% do task_dict.update({ + "app_name": "jedi_tlm_tests", + "opt_confs": ["nwp_gal9_c224", "rrt_equals_dt", "strict_solver"], + "resolution": "C224_MG", + "ancil_resolution": "C224", + "DT": 1800, + "tsteps": 13, + "mpi_parts": 1176, + "threads": 4, }) %} {% elif task_ns.conf_name == "integration_tests" %} @@ -262,19 +306,22 @@ {# List of configuration names that have no kgo #} {% set no_kgo = [ - "id_tlm_tests_default-C12", - "id_tlm_tests_default-1PE-C12", - "tlm_tests_default-C12", - "tlm_tests_default-C12_op", - "tlm_tests_default-1PE-C12", - "tlm_tests_default-4OMP-C12", - "tlm_tests_default-1PE-4OMP-C12", - "tlm_tests_default-dry-C12", - "tlm_tests_default-dry-4OMP-C12", - "tlm_tests_default-dry-1PE-C12", - "tlm_tests_default-dry-1PE-4OMP-C12", - "tlm_tests_default-relaxed_solver-C12", - "tlm_tests_default-relaxed_solver-1PE-C12" + "id_tlm_tests_nwp_gal9-C12_MG", + "id_tlm_tests_nwp_gal9-1PE-C12_MG", + "tlm_tests_nwp_gal9-C12_MG", + "tlm_tests_nwp_gal9-C12_MG_op", + "tlm_tests_nwp_gal9-1PE-C12_MG", + "tlm_tests_nwp_gal9-4OMP-C12_MG", + "tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG", + "tlm_tests_nwp_gal9-1PE-4OMP-C12_MG", + "tlm_tests_nwp_gal9-dry-C12_MG", + "tlm_tests_nwp_gal9-dry-4OMP-C12_MG", + "tlm_tests_nwp_gal9-dry-1PE-C12_MG", + "tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG", + "tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG", + "tlm_tests_nwp_gal9-4OMP-C224_MG", + "tlm_tests_nwp_gal9-real_increment-4OMP-C224_MG", + "tlm_tests_nwp_gal9-strict_solver-4OMP-C224_MG" ] %} {% if task_ns.conf_name not in no_kgo %} diff --git a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc index 26e8a9af8..b68dc1efc 100644 --- a/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc +++ b/rose-stem/site/common/lfric2lfric/tasks_lfric2lfric.cylc @@ -102,7 +102,21 @@ "opt_confs": ["clim_gal9_ral_seuk","oasis"], "resolution": "C12_C16_lam", "dst_mesh": "seuk_MG", - "dst_name": "multigrid_l1", + "dst_name": "dynamics", + "dst_type": "regional", + "src_mesh": "C24_C12", + "src_name": "C12", + "src_type": "global", + }) %} + +{% elif task_ns.conf_name == "oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc" %} + + {# dst_name will need to change to "dynamics-lbc" when lbc meshes can be read #} + {% do task_dict.update({ + "opt_confs": ["clim_gal9_ral_seuk","oasis","lbc"], + "resolution": "C12_C16_lam", + "dst_mesh": "seuk_MG", + "dst_name": "dynamics-lbc", "dst_type": "regional", "src_mesh": "C24_C12", "src_name": "C12", diff --git a/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc b/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc index b7e58ca4d..a49293d58 100644 --- a/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc +++ b/rose-stem/site/common/lfric_atm/tasks_lfric_atm.cylc @@ -90,9 +90,9 @@ theta", }) %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_1T-C12" %} +{% elif task_ns.conf_name == "nwp_gal9_1T-C12" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C12", "DT": 1800, "tsteps": 36, @@ -105,9 +105,9 @@ {% do task_dict.update({"kgo_checks": []}) %} {% endif %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_2T-C12" %} +{% elif task_ns.conf_name == "nwp_gal9_2T-C12" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C12", "DT": 1800, "tsteps": 36, @@ -120,9 +120,9 @@ {% do task_dict.update({"kgo_checks": []}) %} {% endif %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_1T-C48_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_1T-C48_MG" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C48_MG", "DT": 1800, "tsteps": 36, @@ -136,9 +136,9 @@ {% do task_dict.update({"kgo_checks": []}) %} {% endif %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_2T-C48_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_2T-C48_MG" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C48_MG", "DT": 1800, "tsteps": 36, @@ -152,9 +152,9 @@ {% do task_dict.update({"kgo_checks": []}) %} {% endif %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_4T-C48_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_4T-C48_MG" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C48_MG", "DT": 1800, "tsteps": 36, @@ -168,10 +168,10 @@ {% do task_dict.update({"kgo_checks": []}) %} {% endif %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_3n_1T-C192_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_3n_1T-C192_MG" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C192_MG", "DT": 720, "tsteps": 120, @@ -179,10 +179,10 @@ "threads": 1, }) %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_3n_2T-C192_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_3n_2T-C192_MG" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C192_MG", "DT": 720, "tsteps": 120, @@ -191,10 +191,10 @@ "threads": 2, }) %} -{% elif task_ns.conf_name == "nwp_gal9_noukca_3n_4T-C192_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_3n_4T-C192_MG" %} {% do task_dict.update({ - "opt_confs": ["physics_segmentation","no_dust","um_dump","no_diags"], + "opt_confs": ["physics_segmentation","um_dump","no_diags"], "resolution": "C192_MG", "DT": 720, "tsteps": 120, @@ -245,6 +245,19 @@ "log_level": "error", }) %} +{% elif task_ns.conf_name == "nwp_gal9_ls_and_jedi-C224_MG" %} + + {% do task_dict.update({ + "opt_confs": ["um_dump","ls_and_jedi","june_case"], + "resolution": "C224_MG", + "DT": 720, + "tsteps": 35, + "mpi_parts": 1176, + "wallclock": 10, + "xios_nodes": 4, + "mpi_parts_xios" : 16, + }) %} + {% elif task_ns.conf_name == "nwp_gal9-C896_MG" %} {% do task_dict.update({ @@ -435,12 +448,31 @@ "opt_confs": ["um_dump","no_diags"], "resolution": "C12", "DT": 1800, - "tsteps": 2, + "tsteps": 6, "crun": 2, "mpi_parts": 6, "kgo_checks": ["checksum"], }) %} +{# Share Global Configurations - extended by Performance setups#} +{% elif task_ns.conf_name.startswith("nwp_gal9-C896_MG") %} + + {% do task_dict.update({ + "CXI_MATCH_hybrid": true, + "opt_confs": ["um_dump"], + "resolution": "C896_MG", + "DT": 240, + "tsteps": 120, + "wallclock": 15, + "mpi_parts": 4704, + "xios_nodes": 4, + "mpi_parts_xios" : 128, + "log_level": "info", + "log_to_rank_zero_only": ".true.", + "memory_plot_ex": true, + "plot_str": "plot_map.py $NODAL_DATA_DIR/lfric_diagnostics.nc $PLOT_DIR", + }) %} + {# ###################################################################### #} {# Global Climate jobs #} {# ###################################################################### #} @@ -1159,4 +1191,25 @@ {% endif %} {% endif %} +{# Extensions to the Shared Global Configurations - Performance setups#} +{% if task_ns.conf_name.startswith("nwp_gal9-C896_MG_720t") %} + + {% do task_dict.update({ + "opt_confs": ["um_dump"], + "tsteps": 720, + "wallclock": 60, + "plot_str": "", + "restart_write": false, + }) %} +{% endif %} + +{% if task_ns.conf_name.startswith("nwp_gal9-C896_MG_720t_opDiag") %} + + {% do task_dict.update({ + "opt_confs": ["um_dump","oper_diags_hres"], + }) %} + +{% endif %} + + {% do LOG.debug("Finished in site/common/lfric_atm/tasks_lfric_atm.cylc") %} diff --git a/rose-stem/site/common/lfricinputs/tasks_lfric2um.cylc b/rose-stem/site/common/lfricinputs/tasks_lfric2um.cylc index 882acd685..f8269da61 100644 --- a/rose-stem/site/common/lfricinputs/tasks_lfric2um.cylc +++ b/rose-stem/site/common/lfricinputs/tasks_lfric2um.cylc @@ -36,6 +36,7 @@ "source_dump": "$BIG_DATA_DIR/start_dumps/nwp-gal9/apps1.1/nwp-gal9_N320L70_C224L70.nc", "namelist_src": "um_grid.nml", "memory_plot_ex": true, + "kgo_checks": "", }) %} {% elif task_ns.conf_name == "lfric2um-umlam-C48L70_N512L70" %} diff --git a/rose-stem/site/common/lfricinputs/tasks_lfricinputs.cylc b/rose-stem/site/common/lfricinputs/tasks_lfricinputs.cylc index 59b9d0be4..5f0114935 100644 --- a/rose-stem/site/common/lfricinputs/tasks_lfricinputs.cylc +++ b/rose-stem/site/common/lfricinputs/tasks_lfricinputs.cylc @@ -23,6 +23,9 @@ {% set app_name = task_ns.conf_name.split("-")[0] %} {% do task_dict.update({"app_name": app_name}) %} {% endif %} + {% if "kgo_checks" not in task_dict %} + {% do task_dict.update({"kgo_checks": ["rose_ana"]}) %} + {% endif %} {% endif %} {% do LOG.debug("Finished in site/common/lfricinputs/tasks_lfricinputs.cylc") %} diff --git a/rose-stem/site/common/lfricinputs/tasks_um2lfric.cylc b/rose-stem/site/common/lfricinputs/tasks_um2lfric.cylc index 63035057b..530d5061b 100644 --- a/rose-stem/site/common/lfricinputs/tasks_um2lfric.cylc +++ b/rose-stem/site/common/lfricinputs/tasks_um2lfric.cylc @@ -141,6 +141,7 @@ "var_res_src": "", "namelist_src": "um_grid.nml", "memory_plot_ex": true, + "kgo_checks": "", }) %} {% elif task_ns.conf_name == "um2lfric-protogal-N320L70_C48L70" %} diff --git a/rose-stem/site/common/linear_model/tasks_linear_model.cylc b/rose-stem/site/common/linear_model/tasks_linear_model.cylc index 23b91946c..fb054999f 100644 --- a/rose-stem/site/common/linear_model/tasks_linear_model.cylc +++ b/rose-stem/site/common/linear_model/tasks_linear_model.cylc @@ -13,7 +13,7 @@ "DT": 1800, "tsteps": 12, "mpi_parts": 6, - "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 70 linear_model-nwp-gal9_C12 theta:exner:rho:u_in_w2h:v_in_w2h:w_in_wth:m_v:m_cl:m_r:m_s 120:0:5", + "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 70 linear_model-nwp-gal9_C12 theta:exner:rho:u_in_w3:v_in_w3:m_v:m_cl:m_r:m_cf 120:0:5", }) %} {% elif task_ns.conf_name == "nwp_gal9-C224_MG" %} @@ -27,8 +27,8 @@ "xios_nodes": 4, "mpi_parts_xios" : 16, "log_level": "debug", + "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 70 linear_model-nwp-gal9_C224 theta:exner:rho:u_in_w3 120:0:5", "tech-tests_wallclock": 30, - "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 70 linear_model-nwp-gal9_C224 theta:exner:rho:u_in_w2h 120:0:5", }) %} {% elif task_ns.conf_name == "nwp_gal9_random-C12_MG" %} @@ -39,7 +39,7 @@ "DT": 1800, "tsteps": 12, "mpi_parts": 6, - "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 70 linear_model-nwp-gal9_random theta:exner:rho:u_in_w2h:v_in_w2h:w_in_wth:m_v:m_cl:m_r:m_s 120:0:5", + "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 70 linear_model-nwp-gal9_random theta:exner:rho:u_in_w3:v_in_w3:m_v:m_cl:m_r:m_cf 120:0:5", }) %} {% elif task_ns.conf_name == "nwp_gal9_zero-C12_MG" %} @@ -50,6 +50,7 @@ "DT": 1800, "tsteps": 12, "mpi_parts": 6, + "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 70 linear_model-nwp-gal9_random theta:exner:rho:m_v:m_cl:m_r:m_cf 120:0:5", }) %} {% elif task_ns.conf_name == "runge-kutta-C12" %} @@ -81,7 +82,7 @@ "DT": 10, "tsteps": 180, "mpi_parts": 12, - "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 10 linear_model-dcmip theta:exner:rho:u_in_w2h:v_in_w2h:w_in_wth 120:0:5" + "plot_str": "linear.py $NODAL_DATA_DIR/lfric_diag.nc $PLOT_DIR 10 linear_model-dcmip theta:exner:rho:u_in_w3:v_in_w3 120:0:5" }) %} {% elif task_ns.conf_name == "canned" %} diff --git a/rose-stem/site/meto/common/bin/launch-exe b/rose-stem/site/meto/common/bin/launch-exe index 192900191..18abe84af 100755 --- a/rose-stem/site/meto/common/bin/launch-exe +++ b/rose-stem/site/meto/common/bin/launch-exe @@ -149,8 +149,28 @@ if [ "${RUN_METHOD}" = "mpiexec" ] ; then if [ "${xios_nodes}" = "0" ] ; then XIOS_OPTS=" : --cpu-bind=depth --np ${XIOS_SERVER_RANKS} " else - XIOS_CORES_PER_NODE="$(( mpi_parts_xios / xios_nodes ))" - XIOS_OPTS=" : --cpu-bind=depth --np ${XIOS_SERVER_RANKS} --ppn ${XIOS_CORES_PER_NODE} " + XIOS_CORES_PER_NODE="$(( mpi_parts_xios / xios_nodes ))" + + XIOS_FRACTIONAL_DEPTH="$(( CORES_PER_NODE / XIOS_CORES_PER_NODE ))" + if (( "${XIOS_FRACTIONAL_DEPTH}" >= 128 )) ; then + XIOS_DEPTH=" --depth 128" + elif (( "${XIOS_FRACTIONAL_DEPTH}" >= 64 )) ; then + XIOS_DEPTH=" --depth 64" + elif (( "${XIOS_FRACTIONAL_DEPTH}" >= 32 )) ; then + XIOS_DEPTH=" --depth 32" + elif (( "${XIOS_FRACTIONAL_DEPTH}" >= 16 )) ; then + XIOS_DEPTH=" --depth 16" + elif (( "${XIOS_FRACTIONAL_DEPTH}" >= 8 )) ; then + XIOS_DEPTH=" --depth 8" + elif (( "${XIOS_FRACTIONAL_DEPTH}" >= 4 )) ; then + XIOS_DEPTH=" --depth 4" + elif (( "${XIOS_FRACTIONAL_DEPTH}" >= 2 )) ; then + XIOS_DEPTH=" --depth 2" + else + XIOS_DEPTH="" + fi + + XIOS_OPTS=" : --cpu-bind=depth --np ${XIOS_SERVER_RANKS}${XIOS_DEPTH} --ppn ${XIOS_CORES_PER_NODE} " fi fi diff --git a/rose-stem/site/meto/common/suite_config_azspice.cylc b/rose-stem/site/meto/common/suite_config_azspice.cylc index d38604881..07e72b220 100644 --- a/rose-stem/site/meto/common/suite_config_azspice.cylc +++ b/rose-stem/site/meto/common/suite_config_azspice.cylc @@ -9,7 +9,7 @@ 'module purge ; '~ 'module use /home/users/lfricadmin/lmod ; ' %} -{% set azspice_compiler_gnu = 'module load lfric/vn3.0' %} +{% set azspice_compiler_gnu = 'module load lfric/vn3.1' %} {% set azspice_coupled_gnu = 'module load xios/2701-oasis ; '~ 'module load oasis' %} @@ -18,7 +18,7 @@ {% set azspice_scitools = 'module load scitools/production-os47-1' %} -{% set azspice_tech = 'module load lfric/vn3.0' %} +{% set azspice_tech = 'module load lfric/vn3.1' %} [[AZSPICE_BASE]] platform = spice @@ -31,8 +31,8 @@ [[AZSPICE_BUILD]] [[[environment]]] - USE_VERNIER=yes - USE_TIMING_WRAPPER=yes + USE_LEGACY_TIMER=true + USE_TIMING_WRAPPER=true [[[directives]]] --gres=tmp:1024 --export=NONE diff --git a/rose-stem/site/meto/common/suite_config_ex1a.cylc b/rose-stem/site/meto/common/suite_config_ex1a.cylc index 7106a8eb6..b1caa833b 100644 --- a/rose-stem/site/meto/common/suite_config_ex1a.cylc +++ b/rose-stem/site/meto/common/suite_config_ex1a.cylc @@ -5,23 +5,29 @@ {# ########################################################################### #} {% do LOG.debug("Entered site/meto/common/suite_config_ex1a.cylc") %} +{% if site_vars.ex_trustzone == "collab" %} +{% set ex1a_base = 'module use /projects/metoff/spackadmin.mon/releases/2025.12.18/ngms' %} +{% else %} {% set ex1a_base = 'module use /common/internal/spack/releases/2025.10.1/ngms' %} +{% endif %} {% set ex1a_compiler_gnu = 'module switch cpe/22.11 cpe/23.05 ; ' ~ 'module load PrgEnv-gnu ; '~ 'module load gcc/12.2.0 ; '~ - 'module load lfric-gnu/12.2.0/3.0+ || true' %} + 'module load cray-mpich/8.1.27 ; '~ + 'module load lfric-gnu/12.2.0/3.1 || true' %} {% set ex1a_compiler_cce = 'module switch PrgEnv-cray PrgEnv-cray/8.4.0 ; ' ~ 'module load cpe/23.05 ; '~ 'module switch cce cce/15.0.0 ; '~ - 'module load lfric-cray/15.0.0/3.0+ || true ' %} + 'module load cray-mpich/8.1.27 ; '~ + 'module load lfric-cray/15.0.0/3.1 || true ' %} -{% set ex1a_coupled_cce = 'module unload xios/2701-h57fm7d || true ; ' ~ +{% set ex1a_coupled_cce = 'module unload xios/2701 || true ; ' ~ 'module load cray-hdf5-parallel ; ' ~ 'module load cray-netcdf-hdf5parallel ; ' ~ 'module use /data/users/moci/modules_ngms/modules ; '~ - 'module load GC4-PrgEnv/2024-01-lfric_apps_coupled_port-cpe23.05/5548.lua ; ' + 'module load GC6-PrgEnv/2026-01-lfric_apps_coupled_port-cpe23.05-mpich8.1.27/5889.lua ; ' 'module load scitools' %} {% set ex1a_coupled_run = '. $BIG_DATA_DIR/ancils/lfric_coupled/ocean/ocean_ancil_GO8p0_CORE_forcing_eORCA025 ; ' ~ @@ -40,24 +46,30 @@ [[[environment]]] BUILD_ROOT = ${TMPDIR} HYPERTHREADS = 1 - CORES_PER_NODE = 128 + CORES_PER_NODE = {{site_vars.node_cores}} NUMA_REGIONS_PER_NODE = 2 LUSTRE_FILESYSTEM = true ROSE_LAUNCHER = 'mpiexec' + OMP_STACKSIZE=1g + + [[EX1A_WEIGHTS]] + inherit = EX1A_BASE [[EX1A_BUILD]] [[[environment]]] TRANSMUTE_INCLUDE_METHOD = specify_include [[[environment]]] - USE_VERNIER=yes - USE_TIMING_WRAPPER=yes + USE_LEGACY_TIMER=true + USE_TIMING_WRAPPER=true [[[directives]]] -l tmpsize=12GB [[EX1A_RUN]] [[[environment]]] {# BIG_DATA_DIR holds ancils and dump files #} -{% if site_vars["host_ex"] == "exz" %} +{% if site_vars["ex_trustzone"] == "collab" %} + BIG_DATA_DIR = '/data/users/lfricadmin.mon/data' +{% elif site_vars["host_ex"] == "exz" %} BIG_DATA_DIR = '/common/internal/lfricdir/data' {% else %} BIG_DATA_DIR = '/data/users/lfricadmin/data' @@ -173,11 +185,28 @@ module list 2>&1 """ + [[EX1A_SCRIPTS]] + inherit = EX1A_TECH + [[EX1A_EXPORT-SOURCE]] inherit=METO_ORIG [[[environment]]] +{% if site_vars["ex_trustzone"] == "collab" %} + PLATFORM_SYNC = false +{% else %} hostname = $(rose host-select {{site_vars.host_ex}}) PLATFORM_SYNC = true +{% endif %} + + [[EX1A_REMOTE_INIT]] + inherit = EX1A_BASE + [[[directives]]] +{% if site_vars["ex_trustzone"] == "collab" %} + -q = collabshared +{% else %} + -q = shared +{% endif %} + -l ncpus=1 [[EX1A_HOUSEKEEPING]] inherit=EX1A_TECH_BASE diff --git a/rose-stem/site/meto/groups/groups_adjoint_tests.cylc b/rose-stem/site/meto/groups/groups_adjoint_tests.cylc index 804f53ee8..402a08529 100644 --- a/rose-stem/site/meto/groups/groups_adjoint_tests.cylc +++ b/rose-stem/site/meto/groups/groups_adjoint_tests.cylc @@ -8,9 +8,9 @@ {# Azspice Groups #} {% do site_groups.update({ "adjoint_tests_azspice_developer": [ - "adjoint_tests_default-C12_azspice_gnu_fast-debug-64bit-rsolver64", - "adjoint_tests_default-C12_azspice_gnu_full-debug-64bit-rsolver64", - "adjoint_tests_varying_ls-C12_azspice_gnu_fast-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_full-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG-varying_LS_azspice_gnu_fast-debug-64bit-rsolver64", "adjoint_tests_azspice_canned", ], "adjoint_tests_azspice": [ @@ -20,7 +20,7 @@ "adjoint_tests_canned_azspice_gnu_fast-debug-64bit-rsolver64", ], "adjoint_tests_azspice_build": [ - "build_adjoint_tests_azspice_gnu_fast-debug-64bit", + "build_adjoint_tests_azspice_gnu_production-32bit", "build_adjoint_tests_azspice_gnu_full-debug-64bit", ], }) %} @@ -28,8 +28,8 @@ {# EX1A Groups #} {% do site_groups.update({ "adjoint_tests_ex1a_developer": [ - "adjoint_tests_default-C12_ex1a_gnu_fast-debug-64bit-rsolver64", - "adjoint_tests_default-C12_ex1a_gnu_full-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit-rsolver64", + "adjoint_tests_nwp_gal9-C12_MG_ex1a_gnu_full-debug-64bit-rsolver64", "adjoint_tests_ex1a_canned", ], "adjoint_tests_ex1a": [ @@ -39,7 +39,7 @@ "adjoint_tests_canned_ex1a_gnu_fast-debug-64bit-rsolver64", ], "adjoint_tests_ex1a_build": [ - "build_adjoint_tests_ex1a_gnu_fast-debug-64bit", + "build_adjoint_tests_ex1a_gnu_production-32bit", "build_adjoint_tests_ex1a_gnu_full-debug-64bit", ], }) %} @@ -64,6 +64,10 @@ "adjoint_tests_azspice_build", "adjoint_tests_ex1a_build", ], + "adjoint_tests_non-working": [ + "adjoint_tests_nwp_gal9-C12_MG_azspice_gnu_production-32bit", + "adjoint_tests_nwp_gal9-C12_MG_ex1a_gnu_production-32bit" + ] }) %} {# Platform Generic Extends #} diff --git a/rose-stem/site/meto/groups/groups_gungho_model.cylc b/rose-stem/site/meto/groups/groups_gungho_model.cylc index 0605786b9..0704f11ad 100644 --- a/rose-stem/site/meto/groups/groups_gungho_model.cylc +++ b/rose-stem/site/meto/groups/groups_gungho_model.cylc @@ -10,6 +10,9 @@ "gungho_model_azspice_developer": [ "gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_azspice_gnu_fast-debug-64bit", "gungho_model_baroclinic-C24_MG_azspice_gnu_fast-debug-64bit", + "gungho_model_baroclinic-C48_MG_azspice_gnu_fast-debug-64bit", + "gungho_model_baroclinic-C48_MG-2panel_azspice_gnu_fast-debug-64bit", + "gungho_model_baroclinic-C48_MG-3panel_azspice_gnu_fast-debug-64bit", "gungho_model_baroclinic-pert-C24_MG_azspice_gnu_fast-debug-64bit", "gungho_model_baroclinic-alt1-C24s_MG_azspice_gnu_fast-debug-64bit", "gungho_model_baroclinic-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit", diff --git a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc index c5dbac60d..1fbfc565b 100644 --- a/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc +++ b/rose-stem/site/meto/groups/groups_jedi_lfric_tests.cylc @@ -8,7 +8,7 @@ {# Azspice Groups #} {% do site_groups.update({ "jedi_lfric_tests_azspice_developer": [ - "jedi_lfric_tests_nwp_gal9-C12_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_runge-kutta-C12_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_runge-kutta-C12_azspice_gnu_full-debug-64bit", "jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_fast-debug-64bit", @@ -16,24 +16,24 @@ "jedi_lfric_tests_forecast_pseudo_default-C12_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_azspice_gnu_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_azspice_gnu_full-debug-64bit", - "jedi_lfric_tests_tlm_forecast_tl_default-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-1PE-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-4OMP-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-C12_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-1PE-C12_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-1PE-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG_azspice_gnu_fast-debug-64bit-rsolver64", "jedi_lfric_tests_azspice_integration_tests", ], "jedi_lfric_tests_op_azspice_developer": [ - "jedi_lfric_tests_tlm_forecast_tl_default-C12_op_azspice_gnu_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_op_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_azspice_gnu_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_op_azspice_gnu_fast-debug-64bit", ], "jedi_lfric_tests_azspice": [ "jedi_lfric_tests_azspice_developer", @@ -44,6 +44,7 @@ ], "jedi_lfric_tests_azspice_build": [ "build_jedi_lfric_tests_azspice_gnu_fast-debug-64bit", + "build_jedi_lfric_tests_azspice_gnu_fast-debug-64bit-rsolver64", "build_jedi_lfric_tests_azspice_gnu_full-debug-64bit", ], }) %} @@ -52,29 +53,34 @@ {# EX1A Groups #} {% do site_groups.update({ "jedi_lfric_tests_ex1a_developer": [ - "jedi_lfric_tests_nwp_gal9-C12_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_runge-kutta-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_forecast_gh-si-for-linear-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_default-C12_ex1a_cce_fast-debug-64bit", "jedi_lfric_tests_forecast_pseudo_pseudomodel-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_forecast_tl_default-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_id_tlm_tests_default-1PE-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-1PE-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-dry-1PE-4OMP-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-C12_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-relaxed_solver-1PE-C12_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_id_tlm_tests_nwp_gal9-1PE-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-real_increment-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-1PE-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-dry-1PE-4OMP-C12_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-strict_solver-4OMP-C12_MG_ex1a_cce_fast-debug-64bit-rsolver64", "jedi_lfric_tests_ex1a_integration_tests", ], "jedi_lfric_tests_op_ex1a_developer": [ - "jedi_lfric_tests_tlm_forecast_tl_default-C12_op_ex1a_cce_fast-debug-64bit", - "jedi_lfric_tests_tlm_tests_default-C12_op_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-C12_MG_op_ex1a_cce_fast-debug-64bit", + ], + "jedi_lfric_tests_ex1a_weekly": [ + "jedi_lfric_tests_tlm_tests_nwp_gal9-4OMP-C224_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-real_increment-4OMP-C224_MG_ex1a_cce_fast-debug-64bit", + "jedi_lfric_tests_tlm_tests_nwp_gal9-strict_solver-4OMP-C224_MG_ex1a_cce_fast-debug-64bit-rsolver64", ], "jedi_lfric_tests_ex1a": [ "jedi_lfric_tests_ex1a_developer", @@ -85,6 +91,7 @@ ], "jedi_lfric_tests_ex1a_build": [ "build_jedi_lfric_tests_ex1a_cce_fast-debug-64bit", + "build_jedi_lfric_tests_ex1a_cce_fast-debug-64bit-rsolver64", ], }) %} @@ -96,6 +103,9 @@ "jedi_lfric_tests_ex1a_developer", "jedi_lfric_tests_integration_tests", ], + "jedi_lfric_tests_weekly": [ + "jedi_lfric_tests_ex1a_weekly", + ], "jedi_lfric_tests": [ "jedi_lfric_tests_developer", "jedi_lfric_tests_azspice", diff --git a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc index 1fb7bbcd6..eca0b1d27 100644 --- a/rose-stem/site/meto/groups/groups_lfric2lfric.cylc +++ b/rose-stem/site/meto/groups/groups_lfric2lfric.cylc @@ -14,6 +14,7 @@ "lfric2lfric_clim_gal9-C24_C12_azspice_gnu_fast-debug-64bit", "lfric2lfric_oasis_clim_gal9-C24_C12_azspice_gnu_fast-debug-64bit", "lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit", + "lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_azspice_gnu_fast-debug-64bit", "lfric2lfric_azspice_canned", ], "lfric2lfric_azspice_extra": [ @@ -41,6 +42,7 @@ "lfric2lfric_clim_gal9-C24_C12_ex1a_cce_fast-debug-64bit", "lfric2lfric_oasis_clim_gal9-C24_C12_ex1a_cce_fast-debug-64bit", "lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_ex1a_cce_fast-debug-64bit", + "lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_ex1a_cce_fast-debug-64bit", "lfric2lfric_ex1a_canned", ], "lfric2lfric_ex1a_extra": [ diff --git a/rose-stem/site/meto/groups/groups_lfric_atm.cylc b/rose-stem/site/meto/groups/groups_lfric_atm.cylc index 444670968..ea319d080 100644 --- a/rose-stem/site/meto/groups/groups_lfric_atm.cylc +++ b/rose-stem/site/meto/groups/groups_lfric_atm.cylc @@ -27,7 +27,6 @@ "lfric_atm_nwp_gal9-pert-C12_azspice_gnu_fast-debug-32bit", "lfric_atm_nwp_casim-C12_azspice_gnu_fast-debug-32bit", "lfric_atm_nwp_coma9-C12_azspice_gnu_fast-debug-32bit", - "lfric_atm_nwp_comorph_dev-C12_azspice_gnu_fast-debug-32bit", "lfric_atm_nwp_gal9_mol-C12_azspice_gnu_fast-debug-32bit", ], "lfric_atm_nwp_azspice": [ @@ -194,15 +193,26 @@ "lfric_atm_nwp_gal9-C224_MG_ex1a_cce_production-32bit", "lfric_atm_nwp_gal9_oper-C224_MG_ex1a_cce_production-32bit", "lfric_atm_nwp_gal9_debug-C224_MG_ex1a_cce_full-debug-32bit", + "lfric_atm_nwp_gal9_ls_and_jedi-C224_MG_ex1a_cce_production-32bit", "lfric_atm_nwp_gal9-C896_MG_ex1a_cce_production-32bit", "lfric_atm_clim_gal9-C48_MG_ex1a_cce_production-32bit", "lfric_atm_ral_ex1a_weekly", "ex1a_omp_C192_cce", "ex1a_omp_gnu", ], + "lfric_atm_ex1a_performance_check": [ + "lfric_atm_ex1a_weekly", + "lfric_atm_nwp_gal9-C896_MG_720t_perfRun0_ex1a_cce_production-32bit", + ], + "lfric_atm_ex1a_performance_runstats": [ + "lfric_atm_nwp_gal9-C896_MG_720t_perfRun1_ex1a_cce_production-32bit", + "lfric_atm_nwp_gal9-C896_MG_720t_perfRun2_ex1a_cce_production-32bit", + "lfric_atm_nwp_gal9-C896_MG_720t_perfRun3_ex1a_cce_production-32bit", + "lfric_atm_nwp_gal9-C896_MG_720t_perfRun4_ex1a_cce_production-32bit", + ], "lfric_atm_ex1a_threaded": [ - "lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_full-debug-32bit", - "lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex1a_cce_production-32bit", + "lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_full-debug-32bit", + "lfric_atm_nwp_gal9_4T-C48_MG_ex1a_cce_production-32bit", "lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_cce_fast-debug-32bit", "lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_cce_production-32bit", "lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_gnu_fast-debug-32bit", @@ -215,35 +225,35 @@ "ex1a_omp_gnu", ], "ex1a_omp_C12_cce": [ - "lfric_atm_nwp_gal9_noukca_1T-C12_ex1a_cce_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_2T-C12_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_1T-C12_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_2T-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_clim_gal9_1T-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_clim_gal9_2T-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_clim_gal9_chem_1T-C12_ex1a_cce_fast-debug-32bit", "lfric_atm_clim_gal9_chem_2T-C12_ex1a_cce_fast-debug-32bit", ], "ex1a_omp_C48_cce": [ - "lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex1a_cce_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit", "lfric_atm_clim_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit", "lfric_atm_clim_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit", "lfric_atm_clim_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit", ], "ex1a_omp_C192_cce": [ - "lfric_atm_nwp_gal9_noukca_3n_1T-C192_MG_ex1a_cce_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_3n_2T-C192_MG_ex1a_cce_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_3n_4T-C192_MG_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_3n_1T-C192_MG_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_3n_2T-C192_MG_ex1a_cce_fast-debug-32bit", + "lfric_atm_nwp_gal9_3n_4T-C192_MG_ex1a_cce_fast-debug-32bit", ], "ex1a_omp_gnu": [ - "lfric_atm_nwp_gal9_noukca_1T-C12_ex1a_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_2T-C12_ex1a_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex1a_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex1a_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_3n_1T-C192_MG_ex1a_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_3n_2T-C192_MG_ex1a_gnu_fast-debug-32bit", - "lfric_atm_nwp_gal9_noukca_3n_4T-C192_MG_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_1T-C12_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_2T-C12_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_1T-C48_MG_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_2T-C48_MG_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_4T-C48_MG_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_3n_1T-C192_MG_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_3n_2T-C192_MG_ex1a_gnu_fast-debug-32bit", + "lfric_atm_nwp_gal9_3n_4T-C192_MG_ex1a_gnu_fast-debug-32bit", "lfric_atm_clim_gal9_1T-C12_ex1a_gnu_fast-debug-32bit", "lfric_atm_clim_gal9_2T-C12_ex1a_gnu_fast-debug-32bit", "lfric_atm_clim_gal9_chem_1T-C12_ex1a_gnu_fast-debug-32bit", diff --git a/rose-stem/site/meto/groups/groups_linear_model.cylc b/rose-stem/site/meto/groups/groups_linear_model.cylc index b584e591e..062689d42 100644 --- a/rose-stem/site/meto/groups/groups_linear_model.cylc +++ b/rose-stem/site/meto/groups/groups_linear_model.cylc @@ -8,6 +8,7 @@ {# Azspice Groups #} {% do site_groups.update({ "linear_model_azspice_developer": [ + "linear_model_nwp_gal9-C12_MG_azspice_gnu_production-32bit", "linear_model_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit", "linear_model_nwp_gal9_random-C12_MG_azspice_gnu_fast-debug-64bit", "linear_model_nwp_gal9_zero-C12_MG_azspice_gnu_fast-debug-64bit", @@ -31,12 +32,21 @@ {# EX1A Groups #} {% do site_groups.update({ "linear_model_ex1a_developer": [ - "linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit", - "linear_model_nwp_gal9_random-C12_MG_ex1a_gnu_fast-debug-64bit", - "linear_model_nwp_gal9_zero-C12_MG_ex1a_gnu_fast-debug-64bit", "linear_model_runge-kutta-C12_ex1a_gnu_fast-debug-64bit", "linear_model_semi-implicit-C12_ex1a_gnu_fast-debug-64bit", "linear_model_dcmip301-C24_ex1a_gnu_fast-debug-64bit", + "linear_model_nwp_gal9_random-C12_MG_ex1a_gnu_fast-debug-64bit", + "linear_model_nwp_gal9_zero-C12_MG_ex1a_gnu_fast-debug-64bit", + "linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit", + "linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-32bit", + "linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-64bit", + "linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-32bit", + "linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-64bit", + "linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-32bit", + "linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit", + "linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-32bit", + "linear_model_nwp_gal9-C12_MG_ex1a_cce_production-64bit", + "linear_model_nwp_gal9-C12_MG_ex1a_cce_production-32bit", "linear_model_ex1a_canned", ], "linear_model_ex1a": [ diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_azspice_gnu_fast-debug-64bit.txt index 02a626e51..5b6183ebe 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40DAA271B80432F1 -Inner product checksum theta = 42418E8249EA97ED -Inner product checksum u = 43F0A73C14A3943D +Inner product checksum rho = 40DAA271B80432EF +Inner product checksum theta = 42418E8249EA97F2 +Inner product checksum u = 43F0A73C14A39446 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C24_MG_azspice_gnu_fast-debug-64bit.txt index ca1a79dc2..52e45dc2f 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2F2B2244799D0 -Inner product checksum theta = 4210411A3418E006 -Inner product checksum u = 4501AC432146D718 +Inner product checksum rho = 40E2F2B224670998 +Inner product checksum theta = 4210411A3415238B +Inner product checksum u = 4501AC43237805FE diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG-2panel_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG-2panel_azspice_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..a85080f2f --- /dev/null +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG-2panel_azspice_gnu_fast-debug-64bit.txt @@ -0,0 +1,3 @@ +Inner product checksum rho = 4102EEF5FABDC767 +Inner product checksum theta = 423041DD8252C278 +Inner product checksum u = 45017CE3BF147F0A diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG-3panel_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG-3panel_azspice_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..b0fc51b6e --- /dev/null +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG-3panel_azspice_gnu_fast-debug-64bit.txt @@ -0,0 +1,3 @@ +Inner product checksum rho = 4102EEF5FABDC769 +Inner product checksum theta = 423041DD8252C27F +Inner product checksum u = 45017CE3BF147F07 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG_azspice_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..28e631548 --- /dev/null +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-C48_MG_azspice_gnu_fast-debug-64bit.txt @@ -0,0 +1,3 @@ +Inner product checksum rho = 4102EEF5FABDC763 +Inner product checksum theta = 423041DD8252C279 +Inner product checksum u = 45017CE3BF147F13 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt1-C24s_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt1-C24s_MG_azspice_gnu_fast-debug-64bit.txt index 1839f3574..849858d0b 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt1-C24s_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt1-C24s_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E31B5B7CB337D5 -Inner product checksum theta = 4210461DE3B34870 -Inner product checksum u = 4500F56A544F1F86 +Inner product checksum rho = 40E31B5BE7BD919A +Inner product checksum theta = 4210461DFF525960 +Inner product checksum u = 4500F52EDECFC16C diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt index 061be97ca..3b2b948c9 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2EB31AEAB0690 -Inner product checksum theta = 42104262EDCF9F78 -Inner product checksum u = 4501DA5CB5DBC24B +Inner product checksum rho = 40E2EB31AEB4C603 +Inner product checksum theta = 42104262EDCEE39B +Inner product checksum u = 4501DA5CB5DBF453 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt index 58c743fce..3ed29f993 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2F34133893AE6 -Inner product checksum theta = 421041C1BC787C3E -Inner product checksum u = 4501D87B2966270E +Inner product checksum rho = 40E2F342C08629AD +Inner product checksum theta = 421041C191162823 +Inner product checksum u = 4501D8905F18DD52 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-pert-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-pert-C24_MG_azspice_gnu_fast-debug-64bit.txt index 6ccaf3715..9f18c821b 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-pert-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_baroclinic-pert-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2E61079810D0E -Inner product checksum theta = 4210435EB2DDC0F1 -Inner product checksum u = 4501348CFD77EA40 +Inner product checksum rho = 40E2E610798110FE +Inner product checksum theta = 4210435EB2DDB675 +Inner product checksum u = 4501348CFD7333AA diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_azspice_gnu_fast-debug-64bit.txt index 019d1c4bd..fd3c666a1 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40FE89845A997E06 -Inner product checksum theta = 4210F00A9EEFEDF3 -Inner product checksum u = 42EF4B7C9D6C01D8 +Inner product checksum rho = 40FE89845A99A701 +Inner product checksum theta = 4210F00A9EEFEDA9 +Inner product checksum u = 42EF4B7C9D609EB3 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200-C24_MG_azspice_gnu_fast-debug-64bit.txt index 64287df9b..0b0b0c4bd 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E8E802280ABCF8 -Inner product checksum theta = 4204E59A63CB78B4 -Inner product checksum u = 4391E522B368BE24 +Inner product checksum rho = 40E8E802280ABD04 +Inner product checksum theta = 4204E59A63CB78B5 +Inner product checksum u = 4391E522B345D96A diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200_realorog-C48_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200_realorog-C48_MG_azspice_gnu_fast-debug-64bit.txt index 0872d11c8..2a87de992 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200_realorog-C48_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip200_realorog-C48_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41094B0D90339E0A -Inner product checksum theta = 4224DF77B2266354 -Inner product checksum u = 438852006BE9E2CD +Inner product checksum rho = 41094B0D90339E11 +Inner product checksum theta = 4224DF77B226634E +Inner product checksum u = 438852006BBF0069 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip301-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip301-C24_MG_azspice_gnu_fast-debug-64bit.txt index 81c9f6506..90f688cf0 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip301-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_dcmip301-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D3FF37BCAE739E -Inner product checksum theta = 41EC4ACBE79A8587 -Inner product checksum u = 44176CD1D18E18FC +Inner product checksum rho = 40D3FF37BCAE7397 +Inner product checksum theta = 41EC4ACBE79A8479 +Inner product checksum u = 44176CD1D18E2AF5 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_deep-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_deep-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt index 862dd9a4e..2f2341411 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_deep-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_deep-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40EEEF2D423E478C -Inner product checksum theta = 42E4D05A8BCEE836 -Inner product checksum u = 475B46A9C47FB04E +Inner product checksum rho = 40EEEF2D423E47A3 +Inner product checksum theta = 42E4D05A8BCEE1DB +Inner product checksum u = 475B46A9C47FB787 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_earth-like-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_earth-like-C24_MG_azspice_gnu_fast-debug-64bit.txt index b151550e6..41856d806 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_earth-like-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_earth-like-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D56C9EE61BBD77 -Inner product checksum theta = 42198C1850B2D34C -Inner product checksum u = 44E3B95E1E2FF310 +Inner product checksum rho = 40D56C9EE61BC3C6 +Inner product checksum theta = 42198C1850B2D755 +Inner product checksum u = 44E3B95E1E224412 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_held-suarez-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_held-suarez-C24_MG_azspice_gnu_fast-debug-64bit.txt index 703cb92c7..a4e540f2a 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_held-suarez-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_held-suarez-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E34359B7C75475 -Inner product checksum theta = 421168C83D5BA43A -Inner product checksum u = 45082CCFC2F9E7D0 +Inner product checksum rho = 40E34359B8C1F51B +Inner product checksum theta = 421168C83D475CC1 +Inner product checksum u = 45082CCFCF94E9A7 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_lfric-real-domain-C48_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_lfric-real-domain-C48_MG_azspice_gnu_fast-debug-64bit.txt index ef2d843f4..8ef5f2873 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_lfric-real-domain-C48_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_lfric-real-domain-C48_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 4122BD52DCC8006A -Inner product checksum theta = 4240B2570BC700C9 -Inner product checksum u = 44F9DB80026D577A +Inner product checksum rho = 4122BD52DCC8C879 +Inner product checksum theta = 4240B2570BC6116F +Inner product checksum u = 44F9DB80028C7ED8 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt index 3a9e384d6..02c3f9431 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt @@ -1,7 +1,7 @@ -Inner product checksum rho = 41002AB9840956BE -Inner product checksum theta = 4204AB102F77F16E -Inner product checksum u = 42156E231FAF40B2 -Inner product checksum mr1 = 4047451938CF964E +Inner product checksum rho = 41002AB8C8C39016 +Inner product checksum theta = 4204AB102FFEA088 +Inner product checksum u = 42156E16EC9E94D3 +Inner product checksum mr1 = 40474517C0369F04 Inner product checksum mr2 = 0 Inner product checksum mr3 = 0 Inner product checksum mr4 = 0 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt index 072ad5f3b..fd6edf7b7 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_azspice_gnu_fast-debug-64bit.txt @@ -1,7 +1,7 @@ -Inner product checksum rho = 410029843CDCD5BA -Inner product checksum theta = 4204AB0A9C94010A -Inner product checksum u = 4218421EDC590CAE -Inner product checksum mr1 = 4047C516C5BD62B3 +Inner product checksum rho = 410029831ECEAE7E +Inner product checksum theta = 4204AB0A9B9CB929 +Inner product checksum u = 421842DE12830D66 +Inner product checksum mr1 = 4047C514B4591394 Inner product checksum mr2 = 0 Inner product checksum mr3 = 0 Inner product checksum mr4 = 0 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-C24_MG_azspice_gnu_fast-debug-64bit.txt index f1aede880..2151738ed 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41030D58C35909BB -Inner product checksum theta = 42475B42A25CA186 -Inner product checksum u = 456062CEF51C1324 +Inner product checksum rho = 41030D58C3582FBC +Inner product checksum theta = 42475B42A261EF2F +Inner product checksum u = 456062CEF51C79C2 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt index 231eb15fe..cbe07ff1d 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt2-C24_MG_op_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41030D6C13692114 -Inner product checksum theta = 42476BF6F9CB0DCA -Inner product checksum u = 4560B547977FC8C4 +Inner product checksum rho = 41030D6C13704D59 +Inner product checksum theta = 42476BF6F9CA5B22 +Inner product checksum u = 4560B5479772DE2C diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt index b1ccd280c..b8bba792e 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr-alt3-C24_MG_azspice_gnu_fast-debug-64bit-rtran32.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41030F18BC7F8C28 -Inner product checksum theta = 42476C6988C931C5 -Inner product checksum u = 4560A0F426171C4B +Inner product checksum rho = 41030F18BA3F41D1 +Inner product checksum theta = 42476C698981F562 +Inner product checksum u = 4560A0F40D52D12B diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_azspice_gnu_fast-debug-64bit.txt index ee57adc90..6e530e5ee 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E316DD570F220F -Inner product checksum theta = 420BC551F61B38E2 -Inner product checksum u = 44FD3CA2A85DEBBE +Inner product checksum rho = 40E316DD570E3D6C +Inner product checksum theta = 420BC551F61B3002 +Inner product checksum u = 44FD3CA2A860113C diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_azspice_gnu_fast-debug-64bit.txt index e429b368a..daabcd1f5 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E3144534D19E42 -Inner product checksum theta = 420BC6A55E4A9D00 -Inner product checksum u = 44FDCE146C2777B3 +Inner product checksum rho = 40E3144534D1406C +Inner product checksum theta = 420BC6A55E4A92B9 +Inner product checksum u = 44FDCE146C254141 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-BiP200x8-500x500_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-BiP200x8-500x500_azspice_gnu_fast-debug-64bit.txt index 5697a8812..ba4c4efc4 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-BiP200x8-500x500_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-BiP200x8-500x500_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E1E481066A1517 -Inner product checksum theta = 421139232C3CEFAD -Inner product checksum u = 4393A3C2C7771420 +Inner product checksum rho = 40E1E481066A12D9 +Inner product checksum theta = 421139232C3CED92 +Inner product checksum u = 4393A3C2C776B521 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_azspice_gnu_fast-debug-64bit.txt index ffb0744c1..b81805f52 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40C1E430BB50B842 -Inner product checksum theta = 41F13953C0455668 -Inner product checksum u = 4393B8DB189F0BA8 +Inner product checksum rho = 40C1E430BB50B00C +Inner product checksum theta = 41F13953C045587E +Inner product checksum u = 4393B8DB189E7930 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_semi-implicit-for-linear-C12_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_semi-implicit-for-linear-C12_azspice_gnu_fast-debug-64bit.txt index c420fe8e4..3678d4bbe 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_semi-implicit-for-linear-C12_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_semi-implicit-for-linear-C12_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ Inner product checksum rho = 40A3EC6A14AC655B Inner product checksum theta = 41BEDEE1880FB475 -Inner product checksum u = 4316BFB1C72C3612 +Inner product checksum u = 4316BFB1C87E4CB4 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_shallow-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_shallow-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt index a4b7337bc..804176505 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_shallow-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_shallow-hot-jupiter-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 400CE3D8ABA81BA3 -Inner product checksum theta = 426EFB4062696458 -Inner product checksum u = 46E90B314646D0A4 +Inner product checksum rho = 400CE3D8AB9EE6EF +Inner product checksum theta = 426EFB40626338A1 +Inner product checksum u = 46E90B31492B9E29 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_azspice_gnu_fast-debug-64bit.txt index ffe89fd94..8f9469a3e 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40CBD086E89B5CBC -Inner product checksum theta = 41E3A4D10A00A1F3 -Inner product checksum u = 4400A7C1E614149E +Inner product checksum rho = 40CBD086E89B5CB8 +Inner product checksum theta = 41E3A4D10A00A1E5 +Inner product checksum u = 4400A7C1E6141466 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-BiP256x8-200x200_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-BiP256x8-200x200_azspice_gnu_fast-debug-64bit.txt index a9509981a..f9a3053f9 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-BiP256x8-200x200_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-BiP256x8-200x200_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40EA1721E2B197EA -Inner product checksum theta = 41F69B200F92D0F4 -Inner product checksum u = 432D54F6E8799F07 +Inner product checksum rho = 40EA1721E2B1BCD4 +Inner product checksum theta = 41F69B200F927E56 +Inner product checksum u = 432D54F6E82B741E diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_azspice_gnu_fast-debug-64bit.txt index bc0ca5515..b3ad8201a 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40DA171CE530F4BE -Inner product checksum theta = 41E69B0DAB767A1C -Inner product checksum u = 431CEA8125082548 +Inner product checksum rho = 40DA171CE3E1C133 +Inner product checksum theta = 41E69B0DAEB5A2EC +Inner product checksum u = 431CEA80FFBD7029 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_azspice_gnu_fast-debug-64bit.txt index 1b24646b6..e2553efc3 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40FA16E969D70AC8 -Inner product checksum theta = 42069BF1BB714707 -Inner product checksum u = 42FFC30F4E941145 +Inner product checksum rho = 40FA16E969D9ADBC +Inner product checksum theta = 42069BF1BB6B3AAE +Inner product checksum u = 42FFC30F50D36E92 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_azspice_gnu_fast-debug-64bit-rtran32.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_azspice_gnu_fast-debug-64bit-rtran32.txt index 00c69e3b5..741150fb7 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_azspice_gnu_fast-debug-64bit-rtran32.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_azspice_gnu_fast-debug-64bit-rtran32.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40EA1719B7A85796 -Inner product checksum theta = 41F69B1F274ACBE8 -Inner product checksum u = 432E6914CA3F2AB7 +Inner product checksum rho = 40EA1719B3F807A5 +Inner product checksum theta = 41F69B1F286ED724 +Inner product checksum u = 432E691969346DF4 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24_MG_azspice_gnu_fast-debug-64bit.txt index 34c6e5650..6385358bd 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D4230A146F2CC0 -Inner product checksum theta = 421AE83CAB39A57E -Inner product checksum u = 44D53ECE9B74C51B +Inner product checksum rho = 40D4230A14790BDD +Inner product checksum theta = 421AE83CAB1DBD5A +Inner product checksum u = 44D53ED2C725DCD9 diff --git a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_azspice_gnu_fast-debug-64bit.txt index 8513b3305..35e317f21 100644 --- a/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/azspice/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D3B0E5F5D41340 -Inner product checksum theta = 421AFAE9E4BE5D88 -Inner product checksum u = 44D4479F148C12A2 +Inner product checksum rho = 40D3B0E4F2F3F788 +Inner product checksum theta = 421AFAEA72C368FC +Inner product checksum u = 44D4523A63DCEC15 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_ex1a_gnu_fast-debug-64bit.txt index e527b8dfb..8e80d1ea5 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_agnesi_hyd_cart-BiP120x8-2000x2000_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40DAA271B80432F0 -Inner product checksum theta = 42418E8249EA97ED -Inner product checksum u = 43F0A73C14A3943C +Inner product checksum rho = 40DAA271B80432EF +Inner product checksum theta = 42418E8249EA97F2 +Inner product checksum u = 43F0A73C14A39445 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 1b949d925..8c67e23f6 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2F2B22483EA3D -Inner product checksum theta = 4210411A3410C3C7 -Inner product checksum u = 4501AC432284CD82 +Inner product checksum rho = 40E2F2B2246A07FD +Inner product checksum theta = 4210411A34141D34 +Inner product checksum u = 4501AC432220ABA1 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-C48_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-C48_MG_ex1a_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..8310a51cf --- /dev/null +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-C48_MG_ex1a_gnu_fast-debug-64bit.txt @@ -0,0 +1,3 @@ +Inner product checksum rho = 4102EEF5FAB1F22F +Inner product checksum theta = 423041DD82543A06 +Inner product checksum u = 45017CE3BDB23B34 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt1-C24s_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt1-C24s_MG_ex1a_gnu_fast-debug-64bit.txt index 09869fdd8..9926f5622 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt1-C24s_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt1-C24s_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E31B4D10BF0DA0 -Inner product checksum theta = 4210461F9BB0AAAE -Inner product checksum u = 4500F4E3AE6CD8D8 +Inner product checksum rho = 40E31B57FB56C28B +Inner product checksum theta = 4210461EBD1C09DD +Inner product checksum u = 4500F50E9B2378D6 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt index 6ffb81194..2cadd1d66 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2EB31AEB7AC54 -Inner product checksum theta = 42104262EDCE8094 -Inner product checksum u = 4501DA5CB6E76460 +Inner product checksum rho = 40E2EB31AE95DD26 +Inner product checksum theta = 42104262EDD1A3D6 +Inner product checksum u = 4501DA5CB56AC4C4 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt3-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt3-C24_MG_ex1a_gnu_fast-debug-64bit.txt index dcdf764c4..70e360c33 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt3-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-alt3-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2F3443865F0C8 -Inner product checksum theta = 421041C0A40F716F -Inner product checksum u = 4501D87BC37CB1BA +Inner product checksum rho = 40E2F344387CD754 +Inner product checksum theta = 421041C0A40ECB7E +Inner product checksum u = 4501D87BC56E88BD diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-pert-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-pert-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 4ddcb7e18..52c76bceb 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-pert-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_baroclinic-pert-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E2E61079810B7E -Inner product checksum theta = 4210435EB2DDAEFC -Inner product checksum u = 4501348CFD711AFA +Inner product checksum rho = 40E2E6107980FD66 +Inner product checksum theta = 4210435EB2DDA492 +Inner product checksum u = 4501348CFD745E06 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_ex1a_gnu_fast-debug-64bit.txt index a33fd4a1b..cf12c4bbc 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_bryan_fritsch-dry-BiP200x10-100x100_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40FE89845A997E06 -Inner product checksum theta = 4210F00A9EEFEDF3 -Inner product checksum u = 42EF4B7C9D6C01D9 +Inner product checksum rho = 40FE89845A99A702 +Inner product checksum theta = 4210F00A9EEFEDA9 +Inner product checksum u = 42EF4B7C9D609EB4 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200-C24_MG_ex1a_gnu_fast-debug-64bit.txt index a449fc5d3..4a3c842e3 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E8E802280ABCFA -Inner product checksum theta = 4204E59A63CB78B2 -Inner product checksum u = 4391E522B31489D4 +Inner product checksum rho = 40E8E802280ABCFD +Inner product checksum theta = 4204E59A63CB78BA +Inner product checksum u = 4391E522B3045453 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200_realorog-C48_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200_realorog-C48_MG_ex1a_gnu_fast-debug-64bit.txt index a4fa9f025..1bc5bbada 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200_realorog-C48_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip200_realorog-C48_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41094B0D90339E14 -Inner product checksum theta = 4224DF77B226634F -Inner product checksum u = 438852006BFEBBA6 +Inner product checksum rho = 41094B0D90339E0A +Inner product checksum theta = 4224DF77B226635A +Inner product checksum u = 438852006C521A1B diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip301-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip301-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 317fe4b7b..ca4b35a8d 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip301-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_dcmip301-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D3FF37BCAE7576 -Inner product checksum theta = 41EC4ACBE79A8562 -Inner product checksum u = 44176CD1D18E1C00 +Inner product checksum rho = 40D3FF37BCAE768E +Inner product checksum theta = 41EC4ACBE79A813C +Inner product checksum u = 44176CD1D18E1F8D diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_deep-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_deep-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt index abd067848..5eb77db6e 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_deep-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_deep-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40EEEF2D423E47A9 -Inner product checksum theta = 42E4D05A8BCEE302 -Inner product checksum u = 475B46A9C47FC6D6 +Inner product checksum rho = 40EEEF2D423E47A6 +Inner product checksum theta = 42E4D05A8BCEDE80 +Inner product checksum u = 475B46A9C47FDD23 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_earth-like-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_earth-like-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 4ef335a94..23e2af56b 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_earth-like-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_earth-like-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D56C9EE61BC02A -Inner product checksum theta = 42198C1850B2D284 -Inner product checksum u = 44E3B95E1E476DC8 +Inner product checksum rho = 40D56C9EE61BC316 +Inner product checksum theta = 42198C1850B2D534 +Inner product checksum u = 44E3B95E1E3659CE diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_held-suarez-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_held-suarez-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 75bfdf0cf..4c22bf942 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_held-suarez-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_held-suarez-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E34359B80C5804 -Inner product checksum theta = 421168C83D4A79F3 -Inner product checksum u = 45082CCFCECDD575 +Inner product checksum rho = 40E34359BE60DD69 +Inner product checksum theta = 421168C83C59A6DF +Inner product checksum u = 45082CD01E2731A4 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_lfric-real-domain-C48_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_lfric-real-domain-C48_MG_ex1a_gnu_fast-debug-64bit.txt index 9a03afb2d..56de6557b 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_lfric-real-domain-C48_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_lfric-real-domain-C48_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 4122BD52DCC6D87A -Inner product checksum theta = 4240B2570BC5F2DA -Inner product checksum u = 44F9DB8002644CBC +Inner product checksum rho = 4122BD52DCC9E6EB +Inner product checksum theta = 4240B2570BC5E580 +Inner product checksum u = 44F9DB8002ADEC3D diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt index 3a9e384d6..02c3f9431 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-lam-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt @@ -1,7 +1,7 @@ -Inner product checksum rho = 41002AB9840956BE -Inner product checksum theta = 4204AB102F77F16E -Inner product checksum u = 42156E231FAF40B2 -Inner product checksum mr1 = 4047451938CF964E +Inner product checksum rho = 41002AB8C8C39016 +Inner product checksum theta = 4204AB102FFEA088 +Inner product checksum u = 42156E16EC9E94D3 +Inner product checksum mr1 = 40474517C0369F04 Inner product checksum mr2 = 0 Inner product checksum mr3 = 0 Inner product checksum mr4 = 0 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt index 072ad5f3b..fd6edf7b7 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_robert-moist-smag-BiP100x8-10x10_ex1a_gnu_fast-debug-64bit.txt @@ -1,7 +1,7 @@ -Inner product checksum rho = 410029843CDCD5BA -Inner product checksum theta = 4204AB0A9C94010A -Inner product checksum u = 4218421EDC590CAE -Inner product checksum mr1 = 4047C516C5BD62B3 +Inner product checksum rho = 410029831ECEAE7E +Inner product checksum theta = 4204AB0A9B9CB929 +Inner product checksum u = 421842DE12830D66 +Inner product checksum mr1 = 4047C514B4591394 Inner product checksum mr2 = 0 Inner product checksum mr3 = 0 Inner product checksum mr4 = 0 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 7e1dfb2bf..fa464e671 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41030D58C358841C -Inner product checksum theta = 42475B42A25BD24C -Inner product checksum u = 456062CEF51ADA01 +Inner product checksum rho = 41030D58C3590812 +Inner product checksum theta = 42475B42A25E97B8 +Inner product checksum u = 456062CEF51D4871 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt index 087fd2fad..75ce9ee29 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt2-C24_MG_op_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41030D6C136C4726 -Inner product checksum theta = 42476BF6F9C9E065 -Inner product checksum u = 4560B547977B120F +Inner product checksum rho = 41030D6C1370FF70 +Inner product checksum theta = 42476BF6F9CAD9BF +Inner product checksum u = 4560B54797698F24 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt3-C24_MG_ex1a_gnu_fast-debug-64bit-rtran32.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt3-C24_MG_ex1a_gnu_fast-debug-64bit-rtran32.txt index e42f32057..d3d96a110 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt3-C24_MG_ex1a_gnu_fast-debug-64bit-rtran32.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr-alt3-C24_MG_ex1a_gnu_fast-debug-64bit-rtran32.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 41030F18B9FB67A0 -Inner product checksum theta = 42476C698DF698DD -Inner product checksum u = 4560A0F3DA7365AC +Inner product checksum rho = 41030F18BA556EED +Inner product checksum theta = 42476C6985EDD5A2 +Inner product checksum u = 4560A0F4FB952ACD diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_ex1a_gnu_fast-debug-64bit.txt index 2d5e3b173..23aaf00d6 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E316DD570F67E7 -Inner product checksum theta = 420BC551F61B2ADE -Inner product checksum u = 44FD3CA2A85A5D90 +Inner product checksum rho = 40E316DD570E5057 +Inner product checksum theta = 420BC551F61B391B +Inner product checksum u = 44FD3CA2A85EC12A diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_ex1a_gnu_fast-debug-64bit.txt index 30022c661..75ecd5a6e 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_sbr_lam-n96_MG_lam_rotate_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E3144534D22EC1 -Inner product checksum theta = 420BC6A55E4A8238 -Inner product checksum u = 44FDCE146C25FF50 +Inner product checksum rho = 40E3144534D209FF +Inner product checksum theta = 420BC6A55E4A954D +Inner product checksum u = 44FDCE146C249D82 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-BiP200x8-500x500_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-BiP200x8-500x500_ex1a_gnu_fast-debug-64bit.txt index 5697a8812..ba4c4efc4 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-BiP200x8-500x500_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-BiP200x8-500x500_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40E1E481066A1517 -Inner product checksum theta = 421139232C3CEFAD -Inner product checksum u = 4393A3C2C7771420 +Inner product checksum rho = 40E1E481066A12D9 +Inner product checksum theta = 421139232C3CED92 +Inner product checksum u = 4393A3C2C776B521 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_ex1a_gnu_fast-debug-64bit.txt index 41bb50bf2..adf57f0b7 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_schar_cart-alt2-BiP100x4-1000x1000_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40C1E430BB50BA06 -Inner product checksum theta = 41F13953C045589C -Inner product checksum u = 4393B8DB189D9133 +Inner product checksum rho = 40C1E430BB50B1BB +Inner product checksum theta = 41F13953C0455941 +Inner product checksum u = 4393B8DB189EAE30 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_semi-implicit-for-linear-C12_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_semi-implicit-for-linear-C12_ex1a_gnu_fast-debug-64bit.txt index 9ca596629..92e047db7 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_semi-implicit-for-linear-C12_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_semi-implicit-for-linear-C12_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ Inner product checksum rho = 40A3EC6A14AC655D Inner product checksum theta = 41BEDEE1880FB475 -Inner product checksum u = 4316BFB1C7362BEB +Inner product checksum u = 4316BFB1C87E4218 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_shallow-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_shallow-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 415129215..1251a6b1d 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_shallow-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_shallow-hot-jupiter-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 400CE3D8ABB2DD00 -Inner product checksum theta = 426EFB40626F1444 -Inner product checksum u = 46E90B314334D653 +Inner product checksum rho = 400CE3D8ABA24B4C +Inner product checksum theta = 426EFB406264FDD6 +Inner product checksum u = 46E90B3147CFEAB5 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_ex1a_gnu_fast-debug-64bit.txt index ffe89fd94..8f9469a3e 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_skamarock_klemp_gw_p0-BiP300x8-1000x2000_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40CBD086E89B5CBC -Inner product checksum theta = 41E3A4D10A00A1F3 -Inner product checksum u = 4400A7C1E614149E +Inner product checksum rho = 40CBD086E89B5CB8 +Inner product checksum theta = 41E3A4D10A00A1E5 +Inner product checksum u = 4400A7C1E6141466 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt index dd7d16fd9..4c68af9dc 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40EA1721E2B197EB -Inner product checksum theta = 41F69B200F92D0F4 -Inner product checksum u = 432D54F6E8799F07 +Inner product checksum rho = 40EA1721E2B1BCD4 +Inner product checksum theta = 41F69B200F927E57 +Inner product checksum u = 432D54F6E82B741E diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_ex1a_gnu_fast-debug-64bit.txt index fa2891bb7..7c43065c3 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt1-BiP256x4-200x200_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40DA171CE5311E97 -Inner product checksum theta = 41E69B0DAB753A8E -Inner product checksum u = 431CEA812598E8B0 +Inner product checksum rho = 40DA171CE319AA16 +Inner product checksum theta = 41E69B0DB0A24402 +Inner product checksum u = 431CEA80F2E391C8 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_ex1a_gnu_fast-debug-64bit.txt index 22f2c4445..64502ae9f 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt2-BiP256x16-200x50_op_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40FA16E969D797DC -Inner product checksum theta = 42069BF1BB703F6A -Inner product checksum u = 42FFC30F4ED2B428 +Inner product checksum rho = 40FA16E969D78B0B +Inner product checksum theta = 42069BF1BB70B7A9 +Inner product checksum u = 42FFC30F4F0FCDA2 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt index 075d391fc..bc0f86a1b 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_straka_200m-alt3-BiP256x8-200x200_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40EA171A18309116 -Inner product checksum theta = 41F69B1D66F906CB -Inner product checksum u = 432E68AADCDE17B3 +Inner product checksum rho = 40EA171A18307190 +Inner product checksum theta = 41F69B1D66F943A0 +Inner product checksum u = 432E68AADC8D5EF8 diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24_MG_ex1a_gnu_fast-debug-64bit.txt index 0692e4368..cfaab8a14 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D4230A14F81BCE -Inner product checksum theta = 421AE83CAB4D6A4B -Inner product checksum u = 44D53ED7F85D2DAF +Inner product checksum rho = 40D4230A14ACFCE9 +Inner product checksum theta = 421AE83CAB3C5322 +Inner product checksum u = 44D53ED6B3D6E0DA diff --git a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_ex1a_gnu_fast-debug-64bit.txt index d7a2154e7..45924fc3e 100644 --- a/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/gungho_model/ex1a/checksum_gungho_model_tidally-locked-earth-C24s_rot_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 40D3B0E614A00984 -Inner product checksum theta = 421AFAEA39674732 -Inner product checksum u = 44D455410D2E2D22 +Inner product checksum rho = 40D3B0E5979CA91C +Inner product checksum theta = 421AFAEA87B084F6 +Inner product checksum u = 44D456945F0A4E4A diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_fast-debug-64bit.txt index 9fef2e092..76a23cf15 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_fast-debug-64bit.txt @@ -1 +1 @@ -Inner product checksum theta = 41F6D123019100F3 +Inner product checksum theta = 41F6D12301909313 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_full-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_full-debug-64bit.txt index 9fef2e092..76a23cf15 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_full-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_azspice_gnu_full-debug-64bit.txt @@ -1 +1 @@ -Inner product checksum theta = 41F6D123019100F3 +Inner product checksum theta = 41F6D12301909313 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..6dbf85b1b --- /dev/null +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3FA4FD2C7690DC24 +Inner product checksum theta = 415FF4F8712C6491 +Inner product checksum u = 45673B7E0559C62C +Inner product checksum mr1 = 3F35B15D7C0E86A8 +Inner product checksum mr2 = 3EEAD6BF4FDA7F92 +Inner product checksum mr3 = 3EDFF2E76CAF5FF5 +Inner product checksum mr4 = 3EED395DF2372B29 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt index b17a42b79..007c1751c 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3FA7A1197E0CB9A0 -Inner product checksum theta = 4161FFC69BF205C3 -Inner product checksum u = 4569B9484E575B5E -Inner product checksum mr1 = 3F36C0A882D88E66 -Inner product checksum mr2 = 3EEADFD85794EA13 -Inner product checksum mr3 = 3EDFEC0C984D5704 -Inner product checksum mr4 = 3EED3A950512EB1A +Inner product checksum rho = 3FA79A9D0614EEEE +Inner product checksum theta = 4162215D8ED8A125 +Inner product checksum u = 456A083CF999EC55 +Inner product checksum mr1 = 3F36D11B3C65CF3F +Inner product checksum mr2 = 3EEAE32B46C09D7B +Inner product checksum mr3 = 3EDFEC26C0DD3244 +Inner product checksum mr4 = 3EED3B0E06CBD627 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_fast-debug-64bit.txt index df5359de9..f718f88ba 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 3EECEB00E275F684 -Inner product checksum theta = 40130622675CC417 -Inner product checksum u = 42EF956998B205D3 +Inner product checksum rho = 3EED6D12BBFEDECC +Inner product checksum theta = 4012F2F8A6298AC5 +Inner product checksum u = 42F12DF2D0BF0EFC diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_full-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_full-debug-64bit.txt index df5359de9..f718f88ba 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_full-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_runge-kutta-C12_azspice_gnu_full-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 3EECEB00E275F684 -Inner product checksum theta = 40130622675CC417 -Inner product checksum u = 42EF956998B205D3 +Inner product checksum rho = 3EED6D12BBFEDECC +Inner product checksum theta = 4012F2F8A6298AC5 +Inner product checksum u = 42F12DF2D0BF0EFC diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_azspice_gnu_fast-debug-64bit.txt index 36256062e..7d6d62d97 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_azspice_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3F95A1DDD2EC7839 -Inner product checksum theta = 414000E886CBFB32 -Inner product checksum u = 452CCCFAA0BBF41E -Inner product checksum mr1 = 3F2D2183BE8E5C80 -Inner product checksum mr2 = 3EDF53A45356ADEA -Inner product checksum mr3 = 3ED26AEF2D8453B5 -Inner product checksum mr4 = 3EE009842E269AF6 +Inner product checksum rho = 3F95ACC94441A964 +Inner product checksum theta = 413FD47788AE2B0E +Inner product checksum u = 452CBAADFF659374 +Inner product checksum mr1 = 3F2D499F1DCEDE0B +Inner product checksum mr2 = 3EDF578E9B65451B +Inner product checksum mr3 = 3ED26AFC441BB781 +Inner product checksum mr4 = 3EE00986BD98837B Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_azspice_gnu_fast-debug-64bit.txt index 5ae16e5aa..fc254a564 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_azspice_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3F95A1DF1E431E10 -Inner product checksum theta = 41400115CD2072D9 -Inner product checksum u = 452CCC1C9C56D3B6 -Inner product checksum mr1 = 3F2D21B9057A6428 -Inner product checksum mr2 = 3EDF53C45279F22E -Inner product checksum mr3 = 3ED26AEE8FE0B97C -Inner product checksum mr4 = 3EE009839EC7E10F +Inner product checksum rho = 3F95ACCAC59D64D9 +Inner product checksum theta = 413FD499BD5603B7 +Inner product checksum u = 452CB9ABAE30ABAF +Inner product checksum mr1 = 3F2D49D33C196D4C +Inner product checksum mr2 = 3EDF57AEC293C509 +Inner product checksum mr3 = 3ED26AFB9145F0F5 +Inner product checksum mr4 = 3EE009862BB0DCF3 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..abea1a38d --- /dev/null +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 0 +Inner product checksum theta = 0 +Inner product checksum u = 0 +Inner product checksum mr1 = 0 +Inner product checksum mr2 = 0 +Inner product checksum mr3 = 0 +Inner product checksum mr4 = 0 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_azspice_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..abea1a38d --- /dev/null +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/azspice/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_azspice_gnu_fast-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 0 +Inner product checksum theta = 0 +Inner product checksum u = 0 +Inner product checksum mr1 = 0 +Inner product checksum mr2 = 0 +Inner product checksum mr3 = 0 +Inner product checksum mr4 = 0 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_ex1a_cce_fast-debug-64bit.txt index d3457f776..223d31dbd 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_forecast_gh-si-for-linear-C12_ex1a_cce_fast-debug-64bit.txt @@ -1 +1 @@ -Inner product checksum theta = 41F6D123018FAA92 +Inner product checksum theta = 41F6D123019048BD diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt new file mode 100644 index 000000000..3134a07c3 --- /dev/null +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3FA4FD2A13297D96 +Inner product checksum theta = 415FF4F7791418F7 +Inner product checksum u = 45673B7DB19E7072 +Inner product checksum mr1 = 3F35B160CCE25E2C +Inner product checksum mr2 = 3EEAD6BF59DB2878 +Inner product checksum mr3 = 3EDFF2E76569C104 +Inner product checksum mr4 = 3EED395DCB2F649B +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt index db90ee0d3..9ba16ef2b 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3FA7A119D15694EA -Inner product checksum theta = 4161FFC6B41D6C18 -Inner product checksum u = 4569B9484F679FDB -Inner product checksum mr1 = 3F36C0A85083444F -Inner product checksum mr2 = 3EEADFD859B930EE -Inner product checksum mr3 = 3EDFEC0C98392EF7 -Inner product checksum mr4 = 3EED3A95035B479C +Inner product checksum rho = 3FA79A9D24D80B84 +Inner product checksum theta = 4162215D998A790E +Inner product checksum u = 456A083CF563E471 +Inner product checksum mr1 = 3F36D11B19E12F6E +Inner product checksum mr2 = 3EEAE32B48FCBD56 +Inner product checksum mr3 = 3EDFEC26C094A93A +Inner product checksum mr4 = 3EED3B0E07D01F92 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_runge-kutta-C12_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_runge-kutta-C12_ex1a_cce_fast-debug-64bit.txt index 444cc9574..fb9462c5a 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_runge-kutta-C12_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_runge-kutta-C12_ex1a_cce_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 3EECEB00E275EB48 -Inner product checksum theta = 40130622675CC45A -Inner product checksum u = 42EF956998B2045E +Inner product checksum rho = 3EED6D12BBFEDD01 +Inner product checksum theta = 4012F2F8A6298ACF +Inner product checksum u = 42F12DF2D0BF12C9 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_ex1a_cce_fast-debug-64bit.txt index 7dfc5de39..50ce4226d 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_ex1a_cce_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3F95A1C504B6A918 -Inner product checksum theta = 413FF942C2E563C0 -Inner product checksum u = 452CCCF6ABE0865F -Inner product checksum mr1 = 3F2D21C8E6687010 -Inner product checksum mr2 = 3EDF53AD2309BABA -Inner product checksum mr3 = 3ED26AEFEBB2B535 -Inner product checksum mr4 = 3EE00982584FBC51 +Inner product checksum rho = 3F95ACB014DA78D0 +Inner product checksum theta = 413FCBF88C4910CE +Inner product checksum u = 452CBA65B40AFAB8 +Inner product checksum mr1 = 3F2D49E974B2F080 +Inner product checksum mr2 = 3EDF5792D6D2D34E +Inner product checksum mr3 = 3ED26AFD01439F84 +Inner product checksum mr4 = 3EE00984EA466A8E Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_ex1a_cce_fast-debug-64bit.txt index f6ca49a10..a8eadce8d 100644 --- a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_default-C12_op_ex1a_cce_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3F95A1E1F17F7A09 -Inner product checksum theta = 413FF80D6A5F4BE8 -Inner product checksum u = 452CCB73BB6342D4 -Inner product checksum mr1 = 3F2D21C0C423794A -Inner product checksum mr2 = 3EDF53B78E4C3283 -Inner product checksum mr3 = 3ED26AEF7B3222E8 -Inner product checksum mr4 = 3EE00982FE30ACFA +Inner product checksum rho = 3F95ACCD3EEAC2B8 +Inner product checksum theta = 413FCAAF700BA76A +Inner product checksum u = 452CB8D93BF67253 +Inner product checksum mr1 = 3F2D49E4C797F50E +Inner product checksum mr2 = 3EDF579D1DD1B948 +Inner product checksum mr3 = 3ED26AFC92438788 +Inner product checksum mr4 = 3EE00985A17972EA Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt new file mode 100644 index 000000000..abea1a38d --- /dev/null +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 0 +Inner product checksum theta = 0 +Inner product checksum u = 0 +Inner product checksum mr1 = 0 +Inner product checksum mr2 = 0 +Inner product checksum mr3 = 0 +Inner product checksum mr4 = 0 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_ex1a_cce_fast-debug-64bit.txt new file mode 100644 index 000000000..abea1a38d --- /dev/null +++ b/rose-stem/site/meto/kgos/jedi_lfric_tests/ex1a/checksum_jedi_lfric_tests_tlm_forecast_tl_nwp_gal9-C12_MG_op_ex1a_cce_fast-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 0 +Inner product checksum theta = 0 +Inner product checksum u = 0 +Inner product checksum mr1 = 0 +Inner product checksum mr2 = 0 +Inner product checksum mr3 = 0 +Inner product checksum mr4 = 0 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric2lfric/azspice/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric2lfric/azspice/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_azspice_gnu_fast-debug-64bit.txt new file mode 100644 index 000000000..9d6d34d3e --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric2lfric/azspice/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_azspice_gnu_fast-debug-64bit.txt @@ -0,0 +1,6 @@ +Inner product checksum tile_temperature = 41CA233EF9871AE7 +Inner product checksum u10m = 40A6A7AFFBE6DBC3 +Inner product checksum v10m = 40763D213F2E5A8F +Inner product checksum zh = 418925AC5A968D05 +Inner product checksum theta = 423287E5F56B493F +Inner product checksum u_in_w3 = 4141E4EFDFC04911 diff --git a/rose-stem/site/meto/kgos/lfric2lfric/azspice/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric2lfric/azspice/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit.txt index 66d133e45..b5cf95aa6 100644 --- a/rose-stem/site/meto/kgos/lfric2lfric/azspice/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/lfric2lfric/azspice/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum zh = 41CA60A03DABA9FF -Inner product checksum rho = 40DFDD7E6A34BDAC -Inner product checksum theta = 4235803F52CE127A +Inner product checksum zh = 41EA73B073DF7A64 +Inner product checksum rho = 40FFDD7EF4FB2C54 +Inner product checksum theta = 4255803F59E9AFDB diff --git a/rose-stem/site/meto/kgos/lfric2lfric/ex1a/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric2lfric/ex1a/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_ex1a_cce_fast-debug-64bit.txt new file mode 100644 index 000000000..12fd87ef2 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric2lfric/ex1a/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam-lbc_ex1a_cce_fast-debug-64bit.txt @@ -0,0 +1,6 @@ +Inner product checksum tile_temperature = 41CA233EF98718CA +Inner product checksum u10m = 40A6A7AFFBE6DBCE +Inner product checksum v10m = 40763D213F2E5A72 +Inner product checksum zh = 418925AC5A968D44 +Inner product checksum theta = 423287E5F56B4B74 +Inner product checksum u_in_w3 = 4141E4EFDFC04AEB diff --git a/rose-stem/site/meto/kgos/lfric2lfric/ex1a/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric2lfric/ex1a/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_ex1a_cce_fast-debug-64bit.txt index ca344c562..2e94dcd1b 100644 --- a/rose-stem/site/meto/kgos/lfric2lfric/ex1a/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/lfric2lfric/ex1a/checksum_lfric2lfric_oasis_clim_gal9_C12-ral_seuk_C16_lam_ex1a_cce_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum zh = 41CA60A03DABAA19 -Inner product checksum rho = 40DFDD7E6A34BE8C -Inner product checksum theta = 4235803F52CE13AE +Inner product checksum zh = 41EA73B073DF7BA9 +Inner product checksum rho = 40FFDD7EF4FB1ED0 +Inner product checksum theta = 4255803F59E9B152 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_aquaplanet-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_aquaplanet-C12_azspice_gnu_fast-debug-32bit.txt index 9b9895e08..baad1f3c6 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_aquaplanet-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_aquaplanet-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 468AD8F2 -Inner product checksum theta = 4FD6898F -Inner product checksum u = 6A4E3AC8 -Inner product checksum mr1 = 3F07FDF4 -Inner product checksum mr2 = 369B4D1C -Inner product checksum mr3 = 3413652A -Inner product checksum mr4 = 368E9398 +Inner product checksum rho = 468AD911 +Inner product checksum theta = 4FD68987 +Inner product checksum u = 6A4E39D0 +Inner product checksum mr1 = 3F080026 +Inner product checksum mr2 = 369843BE +Inner product checksum mr3 = 3416CDCB +Inner product checksum mr4 = 36905047 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_camembert_case3_gj1214b-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_camembert_case3_gj1214b-C12_azspice_gnu_fast-debug-32bit.txt index dac455d15..a8808603d 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_camembert_case3_gj1214b-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_camembert_case3_gj1214b-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 44D95711 +Inner product checksum rho = 44D95710 Inner product checksum theta = 5504FC40 -Inner product checksum u = 74276DEB +Inner product checksum u = 74276E1C diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9-C12_azspice_gnu_fast-debug-32bit.txt index ebbf5d1b7..4b640fd26 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D66411 -Inner product checksum theta = 518E95C2 -Inner product checksum u = 6AF4A509 -Inner product checksum mr1 = 3FD1977C -Inner product checksum mr2 = 375C8794 -Inner product checksum mr3 = 3534A85C -Inner product checksum mr4 = 36B9C166 +Inner product checksum rho = 46D6671E +Inner product checksum theta = 518E9CC1 +Inner product checksum u = 6AF4B3E5 +Inner product checksum mr1 = 3FD1DD2C +Inner product checksum mr2 = 3744637E +Inner product checksum mr3 = 3533FB34 +Inner product checksum mr4 = 36C1322A Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9_chem-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9_chem-C12_azspice_gnu_fast-debug-32bit.txt index 208bf5b67..0920e465c 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9_chem-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_clim_gal9_chem-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D66282 -Inner product checksum theta = 518E9697 -Inner product checksum u = 6AF4EDB0 -Inner product checksum mr1 = 3FD1A816 -Inner product checksum mr2 = 372DA48E -Inner product checksum mr3 = 355FEEE4 -Inner product checksum mr4 = 36BADA78 +Inner product checksum rho = 46D66653 +Inner product checksum theta = 518E9990 +Inner product checksum u = 6AF43E1A +Inner product checksum mr1 = 3FD1D04B +Inner product checksum mr2 = 3745B69A +Inner product checksum mr3 = 353019A0 +Inner product checksum mr4 = 36BDF494 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_hd209458b-C24_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_hd209458b-C24_azspice_gnu_fast-debug-32bit.txt index 28b77bf56..53e80d265 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_hd209458b-C24_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_hd209458b-C24_azspice_gnu_fast-debug-32bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 4798D8B7 -Inner product checksum theta = 5840648A -Inner product checksum u = 79BA7DF0 +Inner product checksum rho = 4798D8B6 +Inner product checksum theta = 5840648C +Inner product checksum u = 79BA7D9D diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_casim-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_casim-C12_azspice_gnu_fast-debug-32bit.txt index e8298690a..77784af5b 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_casim-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_casim-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D853A2 -Inner product checksum theta = 518BD97F -Inner product checksum u = 6A8B5D0D -Inner product checksum mr1 = 3FCCB5F5 -Inner product checksum mr2 = 383329FE -Inner product checksum mr3 = 354A12DC -Inner product checksum mr4 = 36D48CC3 -Inner product checksum mr5 = 2C0EBB00 -Inner product checksum mr6 = 354FB8FB +Inner product checksum rho = 46D8578E +Inner product checksum theta = 518BD702 +Inner product checksum u = 6A8A9FF5 +Inner product checksum mr1 = 3FCD79BE +Inner product checksum mr2 = 38309A00 +Inner product checksum mr3 = 353B5ACC +Inner product checksum mr4 = 36D670E9 +Inner product checksum mr5 = 2E296A8A +Inner product checksum mr6 = 3534119C diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_coma9-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_coma9-C12_azspice_gnu_fast-debug-32bit.txt index 575d12f26..fba375852 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_coma9-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_coma9-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D84776 -Inner product checksum theta = 518BD5CA -Inner product checksum u = 6A876EA4 -Inner product checksum mr1 = 3FCFC573 -Inner product checksum mr2 = 37F982D2 -Inner product checksum mr3 = 378F0686 -Inner product checksum mr4 = 37941390 -Inner product checksum mr5 = 36AD80BB +Inner product checksum rho = 46D8451F +Inner product checksum theta = 518BD5CF +Inner product checksum u = 6A871C80 +Inner product checksum mr1 = 3FCF8CE1 +Inner product checksum mr2 = 37E92CD1 +Inner product checksum mr3 = 378E0B27 +Inner product checksum mr4 = 378C60AF +Inner product checksum mr5 = 369846E2 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_comorph_dev-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_comorph_dev-C12_azspice_gnu_fast-debug-32bit.txt deleted file mode 100644 index 689a0c93c..000000000 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_comorph_dev-C12_azspice_gnu_fast-debug-32bit.txt +++ /dev/null @@ -1,9 +0,0 @@ -Inner product checksum rho = 46D833DD -Inner product checksum theta = 518BE345 -Inner product checksum u = 6A861A7A -Inner product checksum mr1 = 3FD12CFE -Inner product checksum mr2 = 37EF6FF7 -Inner product checksum mr3 = 377034CF -Inner product checksum mr4 = 37BA8E17 -Inner product checksum mr5 = 3694BA7A -Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-32bit.txt index 066b82f4f..acf51eab2 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D8395D -Inner product checksum theta = 518BD538 -Inner product checksum u = 6A896534 -Inner product checksum mr1 = 3FD027A8 -Inner product checksum mr2 = 37C25DEC -Inner product checksum mr3 = 35A25CC0 -Inner product checksum mr4 = 371736E2 +Inner product checksum rho = 46D83C03 +Inner product checksum theta = 518BD66C +Inner product checksum u = 6A893E10 +Inner product checksum mr1 = 3FD01810 +Inner product checksum mr2 = 37C7F30E +Inner product checksum mr3 = 35A35CEC +Inner product checksum mr4 = 370161BA Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt index b2ad06d13..b6e13d25a 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C12_azspice_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 40DB07687B63446A -Inner product checksum theta = 42317A99CF4E0BC0 -Inner product checksum u = 45512AE8772F7D84 -Inner product checksum mr1 = 3FFA019FB76BA7A3 -Inner product checksum mr2 = 3EF9206AB8DD06F5 -Inner product checksum mr3 = 3EB3C8E43B077FC8 -Inner product checksum mr4 = 3EE4C554CE5D456C +Inner product checksum rho = 40DB07AB9AFC01EF +Inner product checksum theta = 42317ADC8422F866 +Inner product checksum u = 45511E317DB149A5 +Inner product checksum mr1 = 3FF9FFC388F4C713 +Inner product checksum mr2 = 3EFB93018FC96529 +Inner product checksum mr3 = 3EB5CEE201A20BA4 +Inner product checksum mr4 = 3EE600C8EA2D0F0B Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C48_MG_azspice_gnu_fast-debug-32bit.txt index 4c7eed6cc..10d9b44ca 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C48_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FD32 -Inner product checksum theta = 5392A6D2 -Inner product checksum u = 6A97B8BA -Inner product checksum mr1 = 41CD0576 -Inner product checksum mr2 = 39CBA1DC -Inner product checksum mr3 = 37B5C87C -Inner product checksum mr4 = 39631544 +Inner product checksum rho = 48D7FCF3 +Inner product checksum theta = 5392A6CA +Inner product checksum u = 6A97B62D +Inner product checksum mr1 = 41CD09D2 +Inner product checksum mr2 = 39C5EB06 +Inner product checksum mr3 = 37B3A951 +Inner product checksum mr4 = 395FCEA4 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-pert-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-pert-C12_azspice_gnu_fast-debug-32bit.txt index f8dff9082..64760e2f3 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-pert-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9-pert-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D81310 -Inner product checksum theta = 51944596 -Inner product checksum u = 6B4636E2 -Inner product checksum mr1 = 3FC88E16 -Inner product checksum mr2 = 37A99D46 -Inner product checksum mr3 = 35A2C5C6 -Inner product checksum mr4 = 3788B82C +Inner product checksum rho = 46D812FE +Inner product checksum theta = 51944595 +Inner product checksum u = 6B463661 +Inner product checksum mr1 = 3FC88DAE +Inner product checksum mr2 = 37ABA450 +Inner product checksum mr3 = 35A4CCD4 +Inner product checksum mr4 = 37897CFA Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_azspice_gnu_fast-debug-32bit.txt index 35fdec60e..fe9f49f4c 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FDBE -Inner product checksum theta = 5392A6F9 -Inner product checksum u = 6A97B9FA -Inner product checksum mr1 = 41CD0CB2 -Inner product checksum mr2 = 39D05B98 -Inner product checksum mr3 = 37AD4C2E -Inner product checksum mr4 = 395E937D +Inner product checksum rho = 48D7FDA1 +Inner product checksum theta = 5392A6E1 +Inner product checksum u = 6A97B426 +Inner product checksum mr1 = 41CD1068 +Inner product checksum mr2 = 39CDCF8E +Inner product checksum mr3 = 37B22A3E +Inner product checksum mr4 = 3960D144 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_da-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_da-C12_azspice_gnu_fast-debug-32bit.txt index cd579c1cb..ff1dc8e42 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_da-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_da-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D81241 -Inner product checksum theta = 518BD644 -Inner product checksum u = 6A870A8B -Inner product checksum mr1 = 3FD3D730 -Inner product checksum mr2 = 37E1345C -Inner product checksum mr3 = 35A0FF9C -Inner product checksum mr4 = 36DC35A2 +Inner product checksum rho = 46D812FA +Inner product checksum theta = 518BD71C +Inner product checksum u = 6A87CBC7 +Inner product checksum mr1 = 3FD3E175 +Inner product checksum mr2 = 37DDA610 +Inner product checksum mr3 = 35AD9804 +Inner product checksum mr4 = 36E4050E Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C12_azspice_gnu_full-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C12_azspice_gnu_full-debug-32bit.txt index e07f68014..d4dc86bb5 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C12_azspice_gnu_full-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C12_azspice_gnu_full-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D80460 -Inner product checksum theta = 519522B0 -Inner product checksum u = 6AE6775E -Inner product checksum mr1 = 3FC86149 -Inner product checksum mr2 = 37CD2A44 -Inner product checksum mr3 = 351EE925 -Inner product checksum mr4 = 36F072B8 +Inner product checksum rho = 46D8045A +Inner product checksum theta = 519522AF +Inner product checksum u = 6AE677C8 +Inner product checksum mr1 = 3FC86195 +Inner product checksum mr2 = 37CC5EDC +Inner product checksum mr3 = 35200AA4 +Inner product checksum mr4 = 36F06583 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C48_MG_azspice_gnu_full-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C48_MG_azspice_gnu_full-debug-32bit.txt index c1993e0b9..95689700c 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C48_MG_azspice_gnu_full-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_debug-C48_MG_azspice_gnu_full-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D81496 +Inner product checksum rho = 48D81494 Inner product checksum theta = 53952668 -Inner product checksum u = 6AA4D6EE -Inner product checksum mr1 = 41C831AC -Inner product checksum mr2 = 399A2744 -Inner product checksum mr3 = 37789C51 -Inner product checksum mr4 = 39300921 +Inner product checksum u = 6AA4D6DC +Inner product checksum mr1 = 41C8318B +Inner product checksum mr2 = 3999AAE7 +Inner product checksum mr3 = 3778FB0C +Inner product checksum mr4 = 39305110 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda-C12_azspice_gnu_fast-debug-32bit.txt index 8f87801d6..0d92b82da 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D81952 -Inner product checksum theta = 518BAFFF -Inner product checksum u = 6A8C8B79 -Inner product checksum mr1 = 3FD11C39 -Inner product checksum mr2 = 37E724C0 -Inner product checksum mr3 = 359FEF4C -Inner product checksum mr4 = 37074045 +Inner product checksum rho = 46D8193D +Inner product checksum theta = 518BAFDA +Inner product checksum u = 6A8CB83F +Inner product checksum mr1 = 3FD1216C +Inner product checksum mr2 = 37EA1582 +Inner product checksum mr3 = 35979016 +Inner product checksum mr4 = 36F53919 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda_jada-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda_jada-C12_azspice_gnu_fast-debug-32bit.txt index a5745eb7b..c009453d0 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda_jada-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_eda_jada-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D8137D -Inner product checksum theta = 518BD14C -Inner product checksum u = 6A8868AB -Inner product checksum mr1 = 3FD3A9A6 -Inner product checksum mr2 = 37D9892A -Inner product checksum mr3 = 35B50D72 -Inner product checksum mr4 = 37104F46 +Inner product checksum rho = 46D81432 +Inner product checksum theta = 518BD0DB +Inner product checksum u = 6A88AA11 +Inner product checksum mr1 = 3FD40165 +Inner product checksum mr2 = 37D52121 +Inner product checksum mr3 = 35A5B57C +Inner product checksum mr4 = 36D99E7A Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_mol-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_mol-C12_azspice_gnu_fast-debug-32bit.txt index 60686d791..2a9756a9d 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_mol-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_mol-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D85CA4 -Inner product checksum theta = 5193AF09 -Inner product checksum u = 6A862FDC -Inner product checksum mr1 = 3FD02F73 -Inner product checksum mr2 = 37B8193F -Inner product checksum mr3 = 355AA397 -Inner product checksum mr4 = 36FA519C +Inner product checksum rho = 46D85CAB +Inner product checksum theta = 5193AFF8 +Inner product checksum u = 6A85DAD0 +Inner product checksum mr1 = 3FD03DEE +Inner product checksum mr2 = 37ABF442 +Inner product checksum mr3 = 3538567A +Inner product checksum mr4 = 36E34FE8 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_short-C12_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_short-C12_azspice_gnu_fast-debug-32bit.txt index 12acd49ab..b71654b5e 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_short-C12_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_nwp_gal9_short-C12_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D7FBF0 -Inner product checksum theta = 5195577F -Inner product checksum u = 6B246B78 -Inner product checksum mr1 = 3FC85292 -Inner product checksum mr2 = 38201B0A -Inner product checksum mr3 = 356269E7 -Inner product checksum mr4 = 36F6669E +Inner product checksum rho = 46D80C8A +Inner product checksum theta = 5194ED92 +Inner product checksum u = 6B085AD5 +Inner product checksum mr1 = 3FC88023 +Inner product checksum mr2 = 37C1A81E +Inner product checksum mr3 = 356CD412 +Inner product checksum mr4 = 372B87CE Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3-seuk_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3-seuk_MG_azspice_gnu_fast-debug-32bit.txt index f22aad7e4..406a369aa 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3-seuk_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3-seuk_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 483997CA -Inner product checksum theta = 513548FD -Inner product checksum u = 612F5B34 -Inner product checksum mr1 = 4090F669 -Inner product checksum mr2 = 3589856C -Inner product checksum mr3 = 2FA53E3D -Inner product checksum mr4 = 33F4FD6A -Inner product checksum mr5 = BE7D04E +Inner product checksum rho = 483997C9 +Inner product checksum theta = 513548FE +Inner product checksum u = 612F5B38 +Inner product checksum mr1 = 4090F631 +Inner product checksum mr2 = 3591CCEA +Inner product checksum mr3 = 2FA57746 +Inner product checksum mr4 = 33F4FD79 +Inner product checksum mr5 = BE7D083 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_ens-seuk_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_ens-seuk_MG_azspice_gnu_fast-debug-32bit.txt index 42525bc73..5ff558d35 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_ens-seuk_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_ens-seuk_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 483999D4 -Inner product checksum theta = 51354858 -Inner product checksum u = 612F6179 -Inner product checksum mr1 = 40916617 -Inner product checksum mr2 = 364FE1DF -Inner product checksum mr3 = 2FABFD16 -Inner product checksum mr4 = 33F4FDB5 -Inner product checksum mr5 = BF2197F +Inner product checksum rho = 483999C8 +Inner product checksum theta = 5135485A +Inner product checksum u = 612F6174 +Inner product checksum mr1 = 40916665 +Inner product checksum mr2 = 364416DC +Inner product checksum mr3 = 2FAC1A90 +Inner product checksum mr4 = 33F4FD6C +Inner product checksum mr5 = BF21909 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_mixmol-seuk_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_mixmol-seuk_MG_azspice_gnu_fast-debug-32bit.txt index cb46157c6..2d266dd37 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_mixmol-seuk_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_ral3_mixmol-seuk_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48398C72 +Inner product checksum rho = 48398C6E Inner product checksum theta = 513542FA -Inner product checksum u = 612EE1BF -Inner product checksum mr1 = 409102F8 -Inner product checksum mr2 = 358C6492 -Inner product checksum mr3 = 300104A8 -Inner product checksum mr4 = 3404ABE7 -Inner product checksum mr5 = C14576D +Inner product checksum u = 612EE1CA +Inner product checksum mr1 = 409102F1 +Inner product checksum mr2 = 3592AEA4 +Inner product checksum mr3 = 30010913 +Inner product checksum mr4 = 3404ABD5 +Inner product checksum mr5 = C145771 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_azspice_gnu_fast-debug-32bit.txt index c8d190573..da0cb3435 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 4830B5EE -Inner product checksum theta = 513FD8B1 -Inner product checksum u = 5F74A875 -Inner product checksum mr1 = 4155D3E1 -Inner product checksum mr2 = 3A38BFC2 -Inner product checksum mr3 = 309DE635 +Inner product checksum rho = 4830B5EB +Inner product checksum theta = 513FD8CE +Inner product checksum u = 5F74A78A +Inner product checksum mr1 = 4155BE3F +Inner product checksum mr2 = 3A3E0C78 +Inner product checksum mr3 = 30A03718 Inner product checksum mr4 = 0 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_thai_ben1-C48_MG_azspice_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_thai_ben1-C48_MG_azspice_gnu_fast-debug-32bit.txt index ee291b91a..b97fba172 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_thai_ben1-C48_MG_azspice_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/azspice/checksum_lfric_atm_thai_ben1-C48_MG_azspice_gnu_fast-debug-32bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 486B4A34 -Inner product checksum theta = 51CABF2E -Inner product checksum u = 63C9D90E +Inner product checksum rho = 486B4A32 +Inner product checksum theta = 51CABF2D +Inner product checksum u = 63C9DB14 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_aquaplanet-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_aquaplanet-C12_ex1a_cce_fast-debug-32bit.txt index b262a2e1e..1f49bfe68 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_aquaplanet-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_aquaplanet-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 468AD929 -Inner product checksum theta = 4FD6896F -Inner product checksum u = 6A4E3CAD -Inner product checksum mr1 = 3F07F86E -Inner product checksum mr2 = 3694BA68 -Inner product checksum mr3 = 341247CE -Inner product checksum mr4 = 368A0606 +Inner product checksum rho = 468AD927 +Inner product checksum theta = 4FD68974 +Inner product checksum u = 6A4E3F58 +Inner product checksum mr1 = 3F07FDC4 +Inner product checksum mr2 = 3695CB0F +Inner product checksum mr3 = 3416AF74 +Inner product checksum mr4 = 3688F856 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_camembert_case3_gj1214b-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_camembert_case3_gj1214b-C12_ex1a_cce_fast-debug-32bit.txt index 8e17322f7..5edec3d07 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_camembert_case3_gj1214b-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_camembert_case3_gj1214b-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,3 +1,3 @@ Inner product checksum rho = 44D9577E -Inner product checksum theta = 5504FC06 -Inner product checksum u = 74276D62 +Inner product checksum theta = 5504FC04 +Inner product checksum u = 74276D87 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9-C12_ex1a_cce_fast-debug-32bit.txt index 0d6784f42..6b2aee26c 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D6652A -Inner product checksum theta = 518E93EC -Inner product checksum u = 6AF54A1D -Inner product checksum mr1 = 3FD199FC -Inner product checksum mr2 = 373A4F06 -Inner product checksum mr3 = 35526759 -Inner product checksum mr4 = 36CD3F45 +Inner product checksum rho = 46D6659E +Inner product checksum theta = 518E92B2 +Inner product checksum u = 6AF645B2 +Inner product checksum mr1 = 3FD17BD6 +Inner product checksum mr2 = 374872C0 +Inner product checksum mr3 = 35460093 +Inner product checksum mr4 = 36D513C0 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C12_ex1a_cce_fast-debug-32bit.txt index cdce4e3cb..a8247bf83 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D65056 -Inner product checksum theta = 51925277 -Inner product checksum u = 6B2213D6 -Inner product checksum mr1 = 3FCF401D -Inner product checksum mr2 = 3723DA1E -Inner product checksum mr3 = 353FBE95 -Inner product checksum mr4 = 369202EA +Inner product checksum rho = 46D64EB7 +Inner product checksum theta = 51925204 +Inner product checksum u = 6B220318 +Inner product checksum mr1 = 3FCF4E45 +Inner product checksum mr2 = 37351348 +Inner product checksum mr3 = 353C1842 +Inner product checksum mr4 = 369D1690 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt index ef7de3186..935dab390 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D65CA4 -Inner product checksum theta = 5399FF37 -Inner product checksum u = 6B12F9D3 -Inner product checksum mr1 = 41CC35F8 -Inner product checksum mr2 = 3964700B -Inner product checksum mr3 = 37C885DA -Inner product checksum mr4 = 393CC0EB +Inner product checksum rho = 48D65C71 +Inner product checksum theta = 5399FF3C +Inner product checksum u = 6B12FB2B +Inner product checksum mr1 = 41CC3802 +Inner product checksum mr2 = 3967ECD4 +Inner product checksum mr3 = 37C2B69E +Inner product checksum mr4 = 3941B53E Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C12_ex1a_cce_fast-debug-32bit.txt index fc5094f02..5fff179dc 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D65029 -Inner product checksum theta = 51925282 -Inner product checksum u = 6B222646 -Inner product checksum mr1 = 3FCF441A -Inner product checksum mr2 = 373420D6 -Inner product checksum mr3 = 353B5108 -Inner product checksum mr4 = 369534B7 +Inner product checksum rho = 46D64EEF +Inner product checksum theta = 5192521E +Inner product checksum u = 6B22308E +Inner product checksum mr1 = 3FCF4F09 +Inner product checksum mr2 = 3759E9CC +Inner product checksum mr3 = 354E368D +Inner product checksum mr4 = 36A1E498 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt index 9985fc72a..5f9dc4d3a 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D65C9E -Inner product checksum theta = 5399FF36 -Inner product checksum u = 6B12F9E6 -Inner product checksum mr1 = 41CC34F5 -Inner product checksum mr2 = 39628562 -Inner product checksum mr3 = 37CADBE8 -Inner product checksum mr4 = 393CFC10 +Inner product checksum rho = 48D65C63 +Inner product checksum theta = 5399FF3D +Inner product checksum u = 6B12FB74 +Inner product checksum mr1 = 41CC353D +Inner product checksum mr2 = 3961D6B7 +Inner product checksum mr3 = 37C2B434 +Inner product checksum mr4 = 39414ED7 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt index f9b384e6a..86e53b19c 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D65C98 -Inner product checksum theta = 5399FF37 -Inner product checksum u = 6B12FA76 -Inner product checksum mr1 = 41CC32D9 -Inner product checksum mr2 = 396638BD -Inner product checksum mr3 = 37CAADA4 -Inner product checksum mr4 = 393EB70D +Inner product checksum rho = 48D65C66 +Inner product checksum theta = 5399FF39 +Inner product checksum u = 6B12FCF8 +Inner product checksum mr1 = 41CC350C +Inner product checksum mr2 = 39652046 +Inner product checksum mr3 = 37C39FEA +Inner product checksum mr4 = 394124EC Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem-C12_ex1a_cce_fast-debug-32bit.txt index 9508e0ab5..1803e212b 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D66780 -Inner product checksum theta = 518E9690 -Inner product checksum u = 6AF50DE9 -Inner product checksum mr1 = 3FD15B81 -Inner product checksum mr2 = 37581AA6 -Inner product checksum mr3 = 355FE797 -Inner product checksum mr4 = 36D86CA0 +Inner product checksum rho = 46D665F0 +Inner product checksum theta = 518E903E +Inner product checksum u = 6AF66607 +Inner product checksum mr1 = 3FD1CEB7 +Inner product checksum mr2 = 3750C0F4 +Inner product checksum mr3 = 35308456 +Inner product checksum mr4 = 36C50D71 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_1T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_1T-C12_ex1a_cce_fast-debug-32bit.txt index 3a5681d4e..cd932b385 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_1T-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_1T-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D6516E -Inner product checksum theta = 519250DF -Inner product checksum u = 6B22BA14 -Inner product checksum mr1 = 3FCF2C92 -Inner product checksum mr2 = 3737929A -Inner product checksum mr3 = 35357886 -Inner product checksum mr4 = 36A9CD80 +Inner product checksum rho = 46D64E7A +Inner product checksum theta = 51925011 +Inner product checksum u = 6B22BF73 +Inner product checksum mr1 = 3FCF5905 +Inner product checksum mr2 = 37435010 +Inner product checksum mr3 = 3542184C +Inner product checksum mr4 = 36AEB332 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_2T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_2T-C12_ex1a_cce_fast-debug-32bit.txt index da48a4bed..1d9be2526 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_2T-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_clim_gal9_chem_2T-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D65134 -Inner product checksum theta = 5192506E -Inner product checksum u = 6B22D6CD -Inner product checksum mr1 = 3FCF4DA0 -Inner product checksum mr2 = 3736B1D8 -Inner product checksum mr3 = 353E60FE -Inner product checksum mr4 = 36A0052E +Inner product checksum rho = 46D64DFC +Inner product checksum theta = 51924FF0 +Inner product checksum u = 6B227D3C +Inner product checksum mr1 = 3FCF3F5B +Inner product checksum mr2 = 373A7C56 +Inner product checksum mr3 = 353EAD7B +Inner product checksum mr4 = 36A63314 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_comp_tran_ref_3d_l120-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_comp_tran_ref_3d_l120-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt index 91bb01bc5..8bd71eba7 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_comp_tran_ref_3d_l120-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_comp_tran_ref_3d_l120-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 489A8317 -Inner product checksum theta = 51BA5074 -Inner product checksum u = 5F1192E8 -Inner product checksum mr1 = 4187BC72 -Inner product checksum mr2 = 3AF9734F -Inner product checksum mr3 = 34BC1253 +Inner product checksum rho = 489A8379 +Inner product checksum theta = 51BA505B +Inner product checksum u = 5F118CC2 +Inner product checksum mr1 = 4187C6A4 +Inner product checksum mr2 = 3AF39B2F +Inner product checksum mr3 = 34D56FED Inner product checksum mr4 = 0 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_hd209458b-C24_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_hd209458b-C24_ex1a_cce_fast-debug-32bit.txt index 9c29598f8..0c8494eec 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_hd209458b-C24_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_hd209458b-C24_ex1a_cce_fast-debug-32bit.txt @@ -1,3 +1,3 @@ Inner product checksum rho = 4798D952 -Inner product checksum theta = 58406A9E -Inner product checksum u = 79BA728C +Inner product checksum theta = 58406A9C +Inner product checksum u = 79BA72A4 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_casim-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_casim-C12_ex1a_cce_fast-debug-32bit.txt index 662dc2b95..b2f8542fb 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_casim-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_casim-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D85840 -Inner product checksum theta = 518BD4F3 -Inner product checksum u = 6A8AA24E -Inner product checksum mr1 = 3FCD72EF -Inner product checksum mr2 = 3831BCA2 -Inner product checksum mr3 = 3568BB56 -Inner product checksum mr4 = 36B357D6 -Inner product checksum mr5 = 2EA4F771 -Inner product checksum mr6 = 35562C6C +Inner product checksum rho = 46D85C1E +Inner product checksum theta = 518BD68E +Inner product checksum u = 6A8AB4A2 +Inner product checksum mr1 = 3FCD6B98 +Inner product checksum mr2 = 3834A23C +Inner product checksum mr3 = 35462D21 +Inner product checksum mr4 = 36C2FB8E +Inner product checksum mr5 = 2E9A3459 +Inner product checksum mr6 = 355C98F6 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_coma9-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_coma9-C12_ex1a_cce_fast-debug-32bit.txt index 26acfbf09..8d6f364b6 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_coma9-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_coma9-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D8458C -Inner product checksum theta = 518BD62A -Inner product checksum u = 6A87FCF8 -Inner product checksum mr1 = 3FCF951F -Inner product checksum mr2 = 37E6BD02 -Inner product checksum mr3 = 378A7D17 -Inner product checksum mr4 = 3797816D -Inner product checksum mr5 = 36A1EFBC +Inner product checksum rho = 46D8450A +Inner product checksum theta = 518BD8F0 +Inner product checksum u = 6A87D5CF +Inner product checksum mr1 = 3FCF848A +Inner product checksum mr2 = 37EF578A +Inner product checksum mr3 = 37A268D4 +Inner product checksum mr4 = 37A12861 +Inner product checksum mr5 = 36AF6891 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_dev-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_dev-C12_ex1a_cce_fast-debug-32bit.txt index 86f1a8990..528c8a616 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_dev-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_dev-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D832FB -Inner product checksum theta = 518BE422 -Inner product checksum u = 6A85F6E0 -Inner product checksum mr1 = 3FD14346 -Inner product checksum mr2 = 37F2F57E -Inner product checksum mr3 = 3782C0C7 -Inner product checksum mr4 = 37BAC82C -Inner product checksum mr5 = 368F067F +Inner product checksum rho = 46D832D6 +Inner product checksum theta = 518BE1F6 +Inner product checksum u = 6A86BC76 +Inner product checksum mr1 = 3FD120E6 +Inner product checksum mr2 = 37FAD7AC +Inner product checksum mr3 = 376811C0 +Inner product checksum mr4 = 37BFF8BC +Inner product checksum mr5 = 3697AF6E Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_tb-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_tb-C12_ex1a_cce_fast-debug-32bit.txt index f94eb38a4..c17987500 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_tb-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_comorph_tb-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D85410 -Inner product checksum theta = 518BE004 -Inner product checksum u = 6A85218C -Inner product checksum mr1 = 3FCE9E1F -Inner product checksum mr2 = 37E4C939 -Inner product checksum mr3 = 3788C888 -Inner product checksum mr4 = 3742DF88 -Inner product checksum mr5 = 35FA4066 +Inner product checksum rho = 46D8528E +Inner product checksum theta = 518BDFC0 +Inner product checksum u = 6A84BE51 +Inner product checksum mr1 = 3FCE1718 +Inner product checksum mr2 = 37F0E036 +Inner product checksum mr3 = 37746CB5 +Inner product checksum mr4 = 375B7784 +Inner product checksum mr5 = 35F5451D Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-32bit.txt index fc8830b55..3defd3bad 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D83A35 -Inner product checksum theta = 518BD5F4 -Inner product checksum u = 6A88CB4D -Inner product checksum mr1 = 3FD02BB9 -Inner product checksum mr2 = 37C9A7CA -Inner product checksum mr3 = 35983707 -Inner product checksum mr4 = 37015E80 +Inner product checksum rho = 46D83942 +Inner product checksum theta = 518BD198 +Inner product checksum u = 6A8858C5 +Inner product checksum mr1 = 3FD03D69 +Inner product checksum mr2 = 37C68732 +Inner product checksum mr3 = 35A338B2 +Inner product checksum mr4 = 372B63E6 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt index 5442f5230..1e17cfead 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C12_ex1a_cce_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 40DB07BDB335E70F -Inner product checksum theta = 42317B009699D8CA -Inner product checksum u = 45512CE45FA6102C -Inner product checksum mr1 = 3FF9F65BF11FF695 -Inner product checksum mr2 = 3EFA02DB0ABB2DB2 -Inner product checksum mr3 = 3EB4D691E8F904A6 -Inner product checksum mr4 = 3EE1C81A8EF17282 +Inner product checksum rho = 40DB0770E3192095 +Inner product checksum theta = 42317AE3AD158CC4 +Inner product checksum u = 455118036F27A992 +Inner product checksum mr1 = 3FF9FB92A4B6D4E0 +Inner product checksum mr2 = 3EFA9528278A8038 +Inner product checksum mr3 = 3EB5BDCF89E24FCD +Inner product checksum mr4 = 3EE810E99B341094 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C48_MG_ex1a_cce_fast-debug-32bit.txt index 145f29b4c..5caec27d7 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FDF2 -Inner product checksum theta = 5392A6D4 -Inner product checksum u = 6A97C1C8 -Inner product checksum mr1 = 41CD0A6C -Inner product checksum mr2 = 39CA0FC6 -Inner product checksum mr3 = 37B1AE5A -Inner product checksum mr4 = 39608489 +Inner product checksum rho = 48D7FDC2 +Inner product checksum theta = 5392A6CA +Inner product checksum u = 6A97C06C +Inner product checksum mr1 = 41CCFFD6 +Inner product checksum mr2 = 39CB289D +Inner product checksum mr3 = 37B0138E +Inner product checksum mr4 = 3962555F Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-pert-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-pert-C12_ex1a_cce_fast-debug-32bit.txt index 964ce3a8a..e3aa91e3c 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-pert-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9-pert-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D81330 -Inner product checksum theta = 51944574 -Inner product checksum u = 6B464448 -Inner product checksum mr1 = 3FC884F9 -Inner product checksum mr2 = 379E0A83 -Inner product checksum mr3 = 35A557AC -Inner product checksum mr4 = 378669C2 +Inner product checksum rho = 46D81338 +Inner product checksum theta = 51944576 +Inner product checksum u = 6B463F06 +Inner product checksum mr1 = 3FC88651 +Inner product checksum mr2 = 37A36829 +Inner product checksum mr3 = 35A6D95D +Inner product checksum mr4 = 37887FC4 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_1T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_1T-C12_ex1a_cce_fast-debug-32bit.txt new file mode 100644 index 000000000..c3a2a6d16 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_1T-C12_ex1a_cce_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 46D7F858 +Inner product checksum theta = 518E7E7A +Inner product checksum u = 6B17CC75 +Inner product checksum mr1 = 3FCBD462 +Inner product checksum mr2 = 37AD8A40 +Inner product checksum mr3 = 34B9932D +Inner product checksum mr4 = 36C12B34 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt new file mode 100644 index 000000000..5caec27d7 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 48D7FDC2 +Inner product checksum theta = 5392A6CA +Inner product checksum u = 6A97C06C +Inner product checksum mr1 = 41CCFFD6 +Inner product checksum mr2 = 39CB289D +Inner product checksum mr3 = 37B0138E +Inner product checksum mr4 = 3962555F +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C12_ex1a_cce_fast-debug-32bit.txt new file mode 100644 index 000000000..b3a490ffd --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C12_ex1a_cce_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 46D7F7C0 +Inner product checksum theta = 518E7EA0 +Inner product checksum u = 6B17D322 +Inner product checksum mr1 = 3FCBE140 +Inner product checksum mr2 = 37A8EADE +Inner product checksum mr3 = 349D5EB2 +Inner product checksum mr4 = 36BD9099 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt new file mode 100644 index 000000000..64f8b7725 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 48D7FE02 +Inner product checksum theta = 5392A6B8 +Inner product checksum u = 6A97C654 +Inner product checksum mr1 = 41CD029C +Inner product checksum mr2 = 39CE5000 +Inner product checksum mr3 = 37ACA3FB +Inner product checksum mr4 = 396055DE +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_full-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_full-debug-32bit.txt new file mode 100644 index 000000000..f9df60826 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_2T-C48_MG_ex1a_cce_full-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 48D7FCFF +Inner product checksum theta = 5392A6F0 +Inner product checksum u = 6A97B7D3 +Inner product checksum mr1 = 41CD0DDA +Inner product checksum mr2 = 39CD2EE0 +Inner product checksum mr3 = 37B6DDF3 +Inner product checksum mr4 = 3963190E +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt new file mode 100644 index 000000000..f05ae48b9 --- /dev/null +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 48D7FDF2 +Inner product checksum theta = 5392A6C1 +Inner product checksum u = 6A97C07E +Inner product checksum mr1 = 41CD05C2 +Inner product checksum mr2 = 39C9FA29 +Inner product checksum mr3 = 37B66B12 +Inner product checksum mr4 = 39605796 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_ex1a_cce_fast-debug-32bit.txt index 8ba358720..7d15a5c26 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FE7E -Inner product checksum theta = 5392A6C1 -Inner product checksum u = 6A97C698 -Inner product checksum mr1 = 41CD06AC -Inner product checksum mr2 = 39CFBD73 -Inner product checksum mr3 = 37B289D4 -Inner product checksum mr4 = 39620DAE +Inner product checksum rho = 48D7FE88 +Inner product checksum theta = 5392A6C2 +Inner product checksum u = 6A97BFB9 +Inner product checksum mr1 = 41CD0697 +Inner product checksum mr2 = 39C8DC60 +Inner product checksum mr3 = 37B00779 +Inner product checksum mr4 = 395B6E15 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_cce_fast-debug-32bit.txt index ca8c0b007..bbc606f94 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FC3E -Inner product checksum theta = 5392A694 -Inner product checksum u = 6A97C224 -Inner product checksum mr1 = 41CCE753 -Inner product checksum mr2 = 39CB0912 -Inner product checksum mr3 = 37AB8D81 -Inner product checksum mr4 = 3972959E +Inner product checksum rho = 48D7FC63 +Inner product checksum theta = 5392A688 +Inner product checksum u = 6A97C7E2 +Inner product checksum mr1 = 41CCE1BA +Inner product checksum mr2 = 39CC1EA5 +Inner product checksum mr3 = 37B52B9E +Inner product checksum mr4 = 3971E51F Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_gnu_fast-debug-32bit.txt index 3c702f837..6fbce5e9f 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_gnu_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_coarse_aero_threaded-C48_MG_ex1a_gnu_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FB4D -Inner product checksum theta = 5392A6BF -Inner product checksum u = 6A97B4CF -Inner product checksum mr1 = 41CCE4CA -Inner product checksum mr2 = 39D1AFCE -Inner product checksum mr3 = 37B349DC -Inner product checksum mr4 = 3976F722 +Inner product checksum rho = 48D7FB44 +Inner product checksum theta = 5392A6B6 +Inner product checksum u = 6A97B404 +Inner product checksum mr1 = 41CCE89F +Inner product checksum mr2 = 39CC1B52 +Inner product checksum mr3 = 37AE1DF8 +Inner product checksum mr4 = 397813E2 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_da-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_da-C12_ex1a_cce_fast-debug-32bit.txt index 534b57028..4b98b2ae7 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_da-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_da-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D8145C -Inner product checksum theta = 518BD834 -Inner product checksum u = 6A876B3F -Inner product checksum mr1 = 3FD3B699 -Inner product checksum mr2 = 37DBC694 -Inner product checksum mr3 = 35ACADEE -Inner product checksum mr4 = 36DB4B9D +Inner product checksum rho = 46D81300 +Inner product checksum theta = 518BD591 +Inner product checksum u = 6A86E3C2 +Inner product checksum mr1 = 3FD3C193 +Inner product checksum mr2 = 37E8C1CE +Inner product checksum mr3 = 35B99320 +Inner product checksum mr4 = 36D70E14 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C12_ex1a_cce_full-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C12_ex1a_cce_full-debug-32bit.txt index 72d0bfd81..6b296c277 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C12_ex1a_cce_full-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C12_ex1a_cce_full-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D8046E +Inner product checksum rho = 46D8046D Inner product checksum theta = 519522B0 -Inner product checksum u = 6AE676F3 -Inner product checksum mr1 = 3FC861D0 -Inner product checksum mr2 = 37CF9691 -Inner product checksum mr3 = 351F51C6 -Inner product checksum mr4 = 36EFCBFC +Inner product checksum u = 6AE67712 +Inner product checksum mr1 = 3FC861DE +Inner product checksum mr2 = 37CDBC97 +Inner product checksum mr3 = 352223A1 +Inner product checksum mr4 = 36EFD230 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C48_MG_ex1a_cce_full-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C48_MG_ex1a_cce_full-debug-32bit.txt index 52e4cd78a..4b358888f 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C48_MG_ex1a_cce_full-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_debug-C48_MG_ex1a_cce_full-debug-32bit.txt @@ -1,9 +1,9 @@ Inner product checksum rho = 48D81494 -Inner product checksum theta = 53952666 -Inner product checksum u = 6AA4D6C3 -Inner product checksum mr1 = 41C830E0 -Inner product checksum mr2 = 399AC878 -Inner product checksum mr3 = 3778FE37 -Inner product checksum mr4 = 39300070 +Inner product checksum theta = 53952667 +Inner product checksum u = 6AA4D6DD +Inner product checksum mr1 = 41C83143 +Inner product checksum mr2 = 399A84AB +Inner product checksum mr3 = 377973DB +Inner product checksum mr4 = 3930117B Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda-C12_ex1a_cce_fast-debug-32bit.txt index 0ffd8dce1..7a5e3cff4 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D818D1 -Inner product checksum theta = 518BB098 -Inner product checksum u = 6A8C9CAB -Inner product checksum mr1 = 3FD11FBB -Inner product checksum mr2 = 37EB0B66 -Inner product checksum mr3 = 35A515BE -Inner product checksum mr4 = 37211D7E +Inner product checksum rho = 46D818B8 +Inner product checksum theta = 518BB117 +Inner product checksum u = 6A8D23A8 +Inner product checksum mr1 = 3FD1137A +Inner product checksum mr2 = 37DB360D +Inner product checksum mr3 = 35A031F6 +Inner product checksum mr4 = 370B3EBC Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda_jada-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda_jada-C12_ex1a_cce_fast-debug-32bit.txt index fb4ac2cea..aa2bed702 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda_jada-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_eda_jada-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D812C6 -Inner product checksum theta = 518BCF5C -Inner product checksum u = 6A87F7C7 -Inner product checksum mr1 = 3FD3C782 -Inner product checksum mr2 = 37DC7122 -Inner product checksum mr3 = 35A1102A -Inner product checksum mr4 = 36E23FC6 +Inner product checksum rho = 46D813AE +Inner product checksum theta = 518BD182 +Inner product checksum u = 6A884A33 +Inner product checksum mr1 = 3FD3B2DE +Inner product checksum mr2 = 37DA9C3A +Inner product checksum mr3 = 35940F5E +Inner product checksum mr4 = 3712DD31 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_mol-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_mol-C12_ex1a_cce_fast-debug-32bit.txt index c402287b0..440c859d0 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_mol-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_mol-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D85F7F -Inner product checksum theta = 5193AEF6 -Inner product checksum u = 6A863345 -Inner product checksum mr1 = 3FD02DFA -Inner product checksum mr2 = 37B227E9 -Inner product checksum mr3 = 357CB4FC -Inner product checksum mr4 = 3702610A +Inner product checksum rho = 46D85DEA +Inner product checksum theta = 5193AF22 +Inner product checksum u = 6A865782 +Inner product checksum mr1 = 3FD05C10 +Inner product checksum mr2 = 37AECC7C +Inner product checksum mr3 = 35555AD4 +Inner product checksum mr4 = 36CEE5C2 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C12_ex1a_cce_fast-debug-32bit.txt index b165dd977..a9cda3d60 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D7F5C0 -Inner product checksum theta = 518E7EC5 -Inner product checksum u = 6B17B016 -Inner product checksum mr1 = 3FCBDA24 -Inner product checksum mr2 = 37AC191C -Inner product checksum mr3 = 34A5112E -Inner product checksum mr4 = 36F76E7F +Inner product checksum rho = 46D7F53F +Inner product checksum theta = 518E7EF8 +Inner product checksum u = 6B17A164 +Inner product checksum mr1 = 3FCBDDC0 +Inner product checksum mr2 = 37B65076 +Inner product checksum mr3 = 34AF8D37 +Inner product checksum mr4 = 36FD8E6A Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt index 6332d81a0..2d055cced 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FC55 -Inner product checksum theta = 5392A699 -Inner product checksum u = 6A97BCCA -Inner product checksum mr1 = 41CCEB20 -Inner product checksum mr2 = 39CA8C2C -Inner product checksum mr3 = 37AC2EF8 -Inner product checksum mr4 = 3971DABC +Inner product checksum rho = 48D7FC49 +Inner product checksum theta = 5392A69F +Inner product checksum u = 6A97BDE8 +Inner product checksum mr1 = 41CCE85E +Inner product checksum mr2 = 39CAFA12 +Inner product checksum mr3 = 37ABD166 +Inner product checksum mr4 = 3973E9E8 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C12_ex1a_cce_fast-debug-32bit.txt index 0b7dde6c9..973d78bb8 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D7F524 -Inner product checksum theta = 518E7ECC -Inner product checksum u = 6B17AEDA -Inner product checksum mr1 = 3FCBD438 -Inner product checksum mr2 = 37AA82D7 -Inner product checksum mr3 = 34AF63B2 -Inner product checksum mr4 = 37081DCB +Inner product checksum rho = 46D7F57C +Inner product checksum theta = 518E7EDE +Inner product checksum u = 6B17A83B +Inner product checksum mr1 = 3FCBE8E8 +Inner product checksum mr2 = 37AA5510 +Inner product checksum mr3 = 34A43776 +Inner product checksum mr4 = 36EB4854 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt index bd5515481..a3af9fcda 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,11 @@ -Inner product checksum rho = 48D7FC40 -Inner product checksum theta = 5392A678 -Inner product checksum u = 6A97B83A -Inner product checksum mr1 = 41CCED01 -Inner product checksum mr2 = 39C8DCE2 -Inner product checksum mr3 = 37ADC3D4 -Inner product checksum mr4 = 39774AE9 + +Inner product checksum rho = 48D7FC5D +Inner product checksum theta = 5392A66D +Inner product checksum u = 6A97C28C +Inner product checksum mr1 = 41CCEB8E +Inner product checksum mr2 = 39CA5305 +Inner product checksum mr3 = 37AD7626 +Inner product checksum mr4 = 39706818 +>>>>>>> upstream/main Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_full-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_full-debug-32bit.txt index 77e5ba5ff..e5354a8b9 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_full-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex1a_cce_full-debug-32bit.txt @@ -1,9 +1,10 @@ -Inner product checksum rho = 48D7FB4E -Inner product checksum theta = 5392A6ED -Inner product checksum u = 6A97B55D -Inner product checksum mr1 = 41CCF369 -Inner product checksum mr2 = 39CDEEBC -Inner product checksum mr3 = 37AF72F2 -Inner product checksum mr4 = 3971EA0E +Inner product checksum rho = 48D7FB5E +Inner product checksum theta = 5392A6DE +Inner product checksum u = 6A97B4CC +Inner product checksum mr1 = 41CCEE7C +Inner product checksum mr2 = 39CC8EE4 +Inner product checksum mr3 = 37AE7CC2 +Inner product checksum mr4 = 39706A08 +>>>>>>> upstream/main Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt index 503edf68a..a9ffceead 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 48D7FC1D -Inner product checksum theta = 5392A6B6 -Inner product checksum u = 6A97C299 -Inner product checksum mr1 = 41CCE778 -Inner product checksum mr2 = 39CA2CF8 -Inner product checksum mr3 = 37A8570C -Inner product checksum mr4 = 397292EC +Inner product checksum rho = 48D7FC4A +Inner product checksum theta = 5392A66A +Inner product checksum u = 6A97BE23 +Inner product checksum mr1 = 41CCE6A6 +Inner product checksum mr2 = 39CB60DC +Inner product checksum mr3 = 37AF065D +Inner product checksum mr4 = 3973921C Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_short-C12_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_short-C12_ex1a_cce_fast-debug-32bit.txt index fc875d1dd..453cf594b 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_short-C12_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_nwp_gal9_short-C12_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 46D7FC00 -Inner product checksum theta = 5195576C -Inner product checksum u = 6B246EA5 -Inner product checksum mr1 = 3FC852FF -Inner product checksum mr2 = 381E302C -Inner product checksum mr3 = 35639D20 -Inner product checksum mr4 = 36F6E186 +Inner product checksum rho = 46D80CA6 +Inner product checksum theta = 5194ED76 +Inner product checksum u = 6B08591A +Inner product checksum mr1 = 3FC88034 +Inner product checksum mr2 = 37C26C0C +Inner product checksum mr3 = 35767D74 +Inner product checksum mr4 = 372A0F68 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3-seuk_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3-seuk_MG_ex1a_cce_fast-debug-32bit.txt index 1e9885931..317acc6a4 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3-seuk_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3-seuk_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 483997DA -Inner product checksum theta = 5135490A -Inner product checksum u = 612F5E0C -Inner product checksum mr1 = 4090F5EC -Inner product checksum mr2 = 3599E934 -Inner product checksum mr3 = 2FA5315A -Inner product checksum mr4 = 33F4FD4E -Inner product checksum mr5 = BE85FCC +Inner product checksum rho = 483997DE +Inner product checksum theta = 51354909 +Inner product checksum u = 612F5E11 +Inner product checksum mr1 = 4090F5E4 +Inner product checksum mr2 = 358EB0BA +Inner product checksum mr3 = 2FA519F0 +Inner product checksum mr4 = 33F4FD57 +Inner product checksum mr5 = BE85FEC Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_ens-seuk_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_ens-seuk_MG_ex1a_cce_fast-debug-32bit.txt index 9f0b2b052..7b6d5479c 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_ens-seuk_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_ens-seuk_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 483997EC -Inner product checksum theta = 513548FD -Inner product checksum u = 612F5EB9 -Inner product checksum mr1 = 40910DEE -Inner product checksum mr2 = 35DE4A2C -Inner product checksum mr3 = 2FA75F15 -Inner product checksum mr4 = 33F4FFD3 -Inner product checksum mr5 = BE04B38 +Inner product checksum rho = 483997E3 +Inner product checksum theta = 51354900 +Inner product checksum u = 612F5EB6 +Inner product checksum mr1 = 40910DBB +Inner product checksum mr2 = 3600A9CC +Inner product checksum mr3 = 2FA77A9F +Inner product checksum mr4 = 33F4FFEC +Inner product checksum mr5 = BE04B21 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_mixmol-seuk_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_mixmol-seuk_MG_ex1a_cce_fast-debug-32bit.txt index b3bf80080..24e480b50 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_mixmol-seuk_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_ral3_mixmol-seuk_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ Inner product checksum rho = 48398C6A Inner product checksum theta = 51354302 -Inner product checksum u = 612EDCBA -Inner product checksum mr1 = 4091034B -Inner product checksum mr2 = 3592F0C2 -Inner product checksum mr3 = 300105E3 -Inner product checksum mr4 = 3404AC1D +Inner product checksum u = 612EDCAC +Inner product checksum mr1 = 40910338 +Inner product checksum mr2 = 35876274 +Inner product checksum mr3 = 30010BB7 +Inner product checksum mr4 = 3404AC2D Inner product checksum mr5 = C14A22D Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt index 9006b2022..d6c9e6e85 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_rce-BiP64x64-1500x1500_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 4830B646 -Inner product checksum theta = 513FD832 -Inner product checksum u = 5F74BAEC -Inner product checksum mr1 = 4155B86C -Inner product checksum mr2 = 3A48BCB8 -Inner product checksum mr3 = 30A6CEC1 +Inner product checksum rho = 4830B653 +Inner product checksum theta = 513FD830 +Inner product checksum u = 5F74B058 +Inner product checksum mr1 = 4155BC4A +Inner product checksum mr2 = 3A3F75A2 +Inner product checksum mr3 = 3088CA46 Inner product checksum mr4 = 0 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_scm_ral3_constrain-BiP2x2-50000x50000_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_scm_ral3_constrain-BiP2x2-50000x50000_ex1a_cce_fast-debug-32bit.txt index 8584c5aee..cc75b55c6 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_scm_ral3_constrain-BiP2x2-50000x50000_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_scm_ral3_constrain-BiP2x2-50000x50000_ex1a_cce_fast-debug-32bit.txt @@ -1,9 +1,9 @@ Inner product checksum rho = 434FEE7A -Inner product checksum theta = 4C47E251 +Inner product checksum theta = 4C47E250 Inner product checksum u = 62E3D540 -Inner product checksum mr1 = 3A37FEF3 -Inner product checksum mr2 = 31AEACAC -Inner product checksum mr3 = 2602EE25 -Inner product checksum mr4 = 33BE4E1A -Inner product checksum mr5 = 2A4D1790 -Inner product checksum mr6 = 2C90ABAB +Inner product checksum mr1 = 3A37FF16 +Inner product checksum mr2 = 31AEAC76 +Inner product checksum mr3 = 2602F4FF +Inner product checksum mr4 = 33BD5ACA +Inner product checksum mr5 = 2A4D5AC9 +Inner product checksum mr6 = 2C924CD4 diff --git a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_thai_ben1-C48_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_thai_ben1-C48_MG_ex1a_cce_fast-debug-32bit.txt index 490974e84..e78d4e606 100644 --- a/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_thai_ben1-C48_MG_ex1a_cce_fast-debug-32bit.txt +++ b/rose-stem/site/meto/kgos/lfric_atm/ex1a/checksum_lfric_atm_thai_ben1-C48_MG_ex1a_cce_fast-debug-32bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 486B4A17 -Inner product checksum theta = 51CABEF0 -Inner product checksum u = 63C9A5FD +Inner product checksum rho = 486B4A14 +Inner product checksum theta = 51CABEF1 +Inner product checksum u = 63C9A16C diff --git a/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt index 0a81215b8..c3d509995 100644 --- a/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/lfric_coupled/ex1a/checksum_lfric_coupled_nwp_gal9-C48_ex1a_cce_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 411B540C33AE2137 -Inner product checksum theta = 42735B20484A0071 -Inner product checksum u = 456F43594C8887A8 -Inner product checksum mr1 = 40368412E6CE533E -Inner product checksum mr2 = 3F40052B88481958 -Inner product checksum mr3 = 3F025BCA450F15B7 -Inner product checksum mr4 = 3F366AB08264FA88 +Inner product checksum rho = 411B5407F4CE40FD +Inner product checksum theta = 42735B1EDCE5682D +Inner product checksum u = 456F41EDCEE58D54 +Inner product checksum mr1 = 4036855990B99604 +Inner product checksum mr2 = 3F4021291625C39B +Inner product checksum mr3 = 3F00980BB1AF46A0 +Inner product checksum mr4 = 3F368688EE9DBAD2 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_dcmip301-C24_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_dcmip301-C24_azspice_gnu_fast-debug-64bit.txt index 4148368a6..6b4b2fab9 100644 --- a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_dcmip301-C24_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_dcmip301-C24_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 3F20250B4FE9B9EF -Inner product checksum theta = 403305E848D6E311 -Inner product checksum u = 433053B3FA026478 +Inner product checksum rho = 3F20225948327449 +Inner product checksum theta = 4033068A55E5336A +Inner product checksum u = 433056118E515C60 diff --git a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt index 6a7be832b..48d058c8b 100644 --- a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9-C12_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3FA958F0C1D55513 -Inner product checksum theta = 4161FFBE6B89106C -Inner product checksum u = 456A4D0AF00B4480 -Inner product checksum mr1 = 3F3B888F79EB2E18 -Inner product checksum mr2 = 3EEB3109C670AF3C -Inner product checksum mr3 = 3EDFF31B816930A0 -Inner product checksum mr4 = 3EED42827F73DFDC +Inner product checksum rho = 3FA509A05A373B23 +Inner product checksum theta = 41610F1B6ABD09B0 +Inner product checksum u = 45688F5F19933A2F +Inner product checksum mr1 = 3F35BCF4D7DD3124 +Inner product checksum mr2 = 3EEAFF88125CD2E4 +Inner product checksum mr3 = 3EE049CB61EE38FC +Inner product checksum mr4 = 3EED5E034DF58BB4 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9-C12_MG_azspice_gnu_production-32bit.txt b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9-C12_MG_azspice_gnu_production-32bit.txt new file mode 100644 index 000000000..49730ad8f --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9-C12_MG_azspice_gnu_production-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3D284CEE +Inner product checksum theta = 4B087745 +Inner product checksum u = 6B447884 +Inner product checksum mr1 = 39ADE81D +Inner product checksum mr2 = 37580586 +Inner product checksum mr3 = 37024B58 +Inner product checksum mr4 = 376AFC3F +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9_random-C12_MG_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9_random-C12_MG_azspice_gnu_fast-debug-64bit.txt index c19cd8f5f..b1f6fd6ff 100644 --- a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9_random-C12_MG_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_nwp_gal9_random-C12_MG_azspice_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 40C2C1694FA30DD0 -Inner product checksum theta = 43076DE653AEC2FE -Inner product checksum u = 4697E3FAA368DE1C -Inner product checksum mr1 = 40A1D167F8ADA142 -Inner product checksum mr2 = 40699AF5BDBC4864 -Inner product checksum mr3 = 4069A3412D88D047 -Inner product checksum mr4 = 40697EB0A557078A +Inner product checksum rho = 40AFD0F64A85F322 +Inner product checksum theta = 43076FC46F15B98E +Inner product checksum u = 4697A257F5DA33B8 +Inner product checksum mr1 = 4087B978652013B5 +Inner product checksum mr2 = 406997D34AFE58E4 +Inner product checksum mr3 = 4069A875F066DF80 +Inner product checksum mr4 = 406986D990E6CEA9 Inner product checksum mr5 = 406997D0C9B8EEFB Inner product checksum mr6 = 40699547929283AC diff --git a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_semi-implicit-C12_azspice_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_semi-implicit-C12_azspice_gnu_fast-debug-64bit.txt index f7e9ed399..26185b0b3 100644 --- a/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_semi-implicit-C12_azspice_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/azspice/checksum_linear_model_semi-implicit-C12_azspice_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 3EED280BC778BD3B -Inner product checksum theta = 4012F415A1A3F24B -Inner product checksum u = 43A4936A5FD755CE +Inner product checksum rho = 3EED280BC77910C4 +Inner product checksum theta = 4012F415A1A3DFEB +Inner product checksum u = 43A4936A5FD74DF4 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_dcmip301-C24_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_dcmip301-C24_ex1a_gnu_fast-debug-64bit.txt index a5449d77a..9ea9f30ef 100644 --- a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_dcmip301-C24_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_dcmip301-C24_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 3F20250B300C3D30 -Inner product checksum theta = 403305E8470B6A22 -Inner product checksum u = 433053B3A41C6049 +Inner product checksum rho = 3F20225948390658 +Inner product checksum theta = 4033068A55BC3748 +Inner product checksum u = 433056118E328CBC diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-32bit.txt new file mode 100644 index 000000000..5dfff90ae --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3D284C78 +Inner product checksum theta = 4B087863 +Inner product checksum u = 6B447A8E +Inner product checksum mr1 = 39ADE62A +Inner product checksum mr2 = 37581360 +Inner product checksum mr3 = 37025739 +Inner product checksum mr4 = 376B0645 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt new file mode 100644 index 000000000..06fa02a65 --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_fast-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3FA5099F6003533A +Inner product checksum theta = 41610F1B43DFDDB2 +Inner product checksum u = 45688F5EC2FBF69A +Inner product checksum mr1 = 3F35BCF98E9C5B10 +Inner product checksum mr2 = 3EEAFF88D33E0CFE +Inner product checksum mr3 = 3EE049CB63E270F4 +Inner product checksum mr4 = 3EED5E03840E2812 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_production-32bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_production-32bit.txt new file mode 100644 index 000000000..d1df98ac3 --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_production-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3D284AE2 +Inner product checksum theta = 4B0877EC +Inner product checksum u = 6B4479D3 +Inner product checksum mr1 = 39ADE43E +Inner product checksum mr2 = 37581886 +Inner product checksum mr3 = 37024D8F +Inner product checksum mr4 = 376ADB79 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_production-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_production-64bit.txt new file mode 100644 index 000000000..bcfb6e282 --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_cce_production-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3FA509A35A558386 +Inner product checksum theta = 41610F1C92657C34 +Inner product checksum u = 45688F61E0CB5BE5 +Inner product checksum mr1 = 3F35BCE5306E6416 +Inner product checksum mr2 = 3EEAFF88AFF1C5F2 +Inner product checksum mr3 = 3EE049CB62F1062E +Inner product checksum mr4 = 3EED5E036CB1379F +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-32bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-32bit.txt new file mode 100644 index 000000000..9331aab13 --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3D284C91 +Inner product checksum theta = 4B087777 +Inner product checksum u = 6B4478FE +Inner product checksum mr1 = 39ADE81E +Inner product checksum mr2 = 375811AE +Inner product checksum mr3 = 37025154 +Inner product checksum mr4 = 376AFFAE +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit.txt index 8839d63b9..5a152f61a 100644 --- a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 3FA958F09D97D52D -Inner product checksum theta = 4161FFBE7B6B7DE1 -Inner product checksum u = 456A4D0ACAB467CA -Inner product checksum mr1 = 3F3B888D5EA6A45C -Inner product checksum mr2 = 3EEB310977D9678E -Inner product checksum mr3 = 3EDFF31B705B97D8 -Inner product checksum mr4 = 3EED42824B13222B +Inner product checksum rho = 3FA509A19CBF114C +Inner product checksum theta = 41610F1BFEB0E6B6 +Inner product checksum u = 45688F5FDBD474EE +Inner product checksum mr1 = 3F35BCF304716E6C +Inner product checksum mr2 = 3EEAFF885F22B408 +Inner product checksum mr3 = 3EE049CB62D7CD5C +Inner product checksum mr4 = 3EED5E036E5CC8B3 Inner product checksum mr5 = 0 Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-32bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-32bit.txt new file mode 100644 index 000000000..9331aab13 --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3D284C91 +Inner product checksum theta = 4B087777 +Inner product checksum u = 6B4478FE +Inner product checksum mr1 = 39ADE81E +Inner product checksum mr2 = 375811AE +Inner product checksum mr3 = 37025154 +Inner product checksum mr4 = 376AFFAE +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-64bit.txt new file mode 100644 index 000000000..5a152f61a --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_full-debug-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3FA509A19CBF114C +Inner product checksum theta = 41610F1BFEB0E6B6 +Inner product checksum u = 45688F5FDBD474EE +Inner product checksum mr1 = 3F35BCF304716E6C +Inner product checksum mr2 = 3EEAFF885F22B408 +Inner product checksum mr3 = 3EE049CB62D7CD5C +Inner product checksum mr4 = 3EED5E036E5CC8B3 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-32bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-32bit.txt new file mode 100644 index 000000000..b0bf5b685 --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-32bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3D284D10 +Inner product checksum theta = 4B08771E +Inner product checksum u = 6B447876 +Inner product checksum mr1 = 39ADE4E0 +Inner product checksum mr2 = 3757FB62 +Inner product checksum mr3 = 37024C1A +Inner product checksum mr4 = 376B018E +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-64bit.txt new file mode 100644 index 000000000..7423a529e --- /dev/null +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9-C12_MG_ex1a_gnu_production-64bit.txt @@ -0,0 +1,9 @@ +Inner product checksum rho = 3FA5099CDBEA12B4 +Inner product checksum theta = 41610F1BEE6C742F +Inner product checksum u = 45688F5FC27D3983 +Inner product checksum mr1 = 3F35BCF575283D30 +Inner product checksum mr2 = 3EEAFF88D19CC1C6 +Inner product checksum mr3 = 3EE049CB6313FA43 +Inner product checksum mr4 = 3EED5E03BABE1564 +Inner product checksum mr5 = 0 +Inner product checksum mr6 = 0 diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9_random-C12_MG_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9_random-C12_MG_ex1a_gnu_fast-debug-64bit.txt index 1fba69899..dc566e6c9 100644 --- a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9_random-C12_MG_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_nwp_gal9_random-C12_MG_ex1a_gnu_fast-debug-64bit.txt @@ -1,9 +1,9 @@ -Inner product checksum rho = 40C2C1668AA536C6 -Inner product checksum theta = 43076DE652800BE2 -Inner product checksum u = 4697E3FAA2E5E0C6 -Inner product checksum mr1 = 40A1D167F834C0E0 -Inner product checksum mr2 = 40699AF5BDC7A01E -Inner product checksum mr3 = 4069A3412D91ECF2 -Inner product checksum mr4 = 40697EB0A55E4C2B +Inner product checksum rho = 40AFD0F3325D1D83 +Inner product checksum theta = 43076FC470DF7DDF +Inner product checksum u = 4697A257F73F2A4A +Inner product checksum mr1 = 4087B978405AA662 +Inner product checksum mr2 = 406997D34B3FE4CE +Inner product checksum mr3 = 4069A875F075892B +Inner product checksum mr4 = 406986D990BEDA55 Inner product checksum mr5 = 406997D0C9B8EEFC Inner product checksum mr6 = 40699547929283AD diff --git a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_semi-implicit-C12_ex1a_gnu_fast-debug-64bit.txt b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_semi-implicit-C12_ex1a_gnu_fast-debug-64bit.txt index 3906107bd..f3118f740 100644 --- a/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_semi-implicit-C12_ex1a_gnu_fast-debug-64bit.txt +++ b/rose-stem/site/meto/kgos/linear_model/ex1a/checksum_linear_model_semi-implicit-C12_ex1a_gnu_fast-debug-64bit.txt @@ -1,3 +1,3 @@ -Inner product checksum rho = 3EED280BC779365A -Inner product checksum theta = 4012F415A1A375AE -Inner product checksum u = 43A4936A5FD4C67B +Inner product checksum rho = 3EED280BC7788E7C +Inner product checksum theta = 4012F415A1A479C3 +Inner product checksum u = 43A4936A5FDBA963 diff --git a/rose-stem/site/meto/lfric_atm/tasks_lfric_atm_ex1a.cylc b/rose-stem/site/meto/lfric_atm/tasks_lfric_atm_ex1a.cylc index 4054439c6..776d176ed 100644 --- a/rose-stem/site/meto/lfric_atm/tasks_lfric_atm_ex1a.cylc +++ b/rose-stem/site/meto/lfric_atm/tasks_lfric_atm_ex1a.cylc @@ -76,6 +76,14 @@ "memory": [24, "GB"], }) %} +{% elif task_ns.conf_name == "nwp_gal9-C896_MG" %} + + {% if "-64bit" in task_ns.extras %} + {% do task_dict.update({ + "task_ranks_per_node": 112, + }) %} + {% endif %} + {% endif %} {% if "perftools" in task_ns.compiler %} diff --git a/rose-stem/site/meto/lfricinputs/tasks_lfricinputs_ex1a.cylc b/rose-stem/site/meto/lfricinputs/tasks_lfricinputs_ex1a.cylc index afcbcc157..e82747c68 100644 --- a/rose-stem/site/meto/lfricinputs/tasks_lfricinputs_ex1a.cylc +++ b/rose-stem/site/meto/lfricinputs/tasks_lfricinputs_ex1a.cylc @@ -17,6 +17,12 @@ "memory": [96, "GB"], }) %} +{% elif task_ns.conf_name == "um2lfric-nwp_gal9-N320L70_C224L70" %} + + {% do task_dict.update({ + "memory": [96, "GB"], + }) %} + {% endif %} {% if task_dict %} @@ -27,7 +33,7 @@ "yproc": 14, }) %} {% endif %} - {% if task_dict["app_name"] == "um2lfric" %} + {% if task_dict["app_name"] == "um2lfric" and task_ns.conf_name != "um2lfric-nwp_gal9-N320L70_C224L70"%} {% do task_dict.update({ "xios_nodes": 1, "mpi_parts_xios": 1, diff --git a/rose-stem/site/meto/macros/macros_ex1a.cylc b/rose-stem/site/meto/macros/macros_ex1a.cylc index 70a1229e8..be64728da 100644 --- a/rose-stem/site/meto/macros/macros_ex1a.cylc +++ b/rose-stem/site/meto/macros/macros_ex1a.cylc @@ -5,7 +5,11 @@ {# ########################################################################### #} {% do LOG.debug("Entered site/meto/macros/macros_ex1a.cylc") %} -{% set ex1a_cores_per_node = 128 %} +{% if site_vars.node_type == "genoa" %} + {% set ex1a_cores_per_node = 192 %} +{% else %} + {% set ex1a_cores_per_node = 128 %} +{% endif %} {% set ex1a_socket_per_node = 2 %} {% macro normal_queue(mpi_ranks, @@ -70,16 +74,24 @@ {% set lfric_nodes = possible_nodes %} {% endif %} + {% if site_vars["ex_trustzone"] == "collab" %} + -q=collab + {% else %} -q=normal + {% endif %} -l select={{ lfric_nodes + ocean_nodes|int + river_nodes|int + - xios_nodes|int }} + xios_nodes|int }}:coretype={{site_vars.node_type}}:mem={{site_vars.node_mem}}GB{{site_vars.crayhost}} {% endmacro %} {% macro shared_queue(cores) %} + {% if site_vars["ex_trustzone"] == "collab" %} + -q=collabshared + {% else %} -q=shared + {% endif %} -l ncpus={{ cores }} {% endmacro %} diff --git a/rose-stem/site/meto/suite_config.cylc b/rose-stem/site/meto/suite_config.cylc index a4a5b03d5..e909471e0 100644 --- a/rose-stem/site/meto/suite_config.cylc +++ b/rose-stem/site/meto/suite_config.cylc @@ -6,8 +6,12 @@ {% do LOG.debug("Entered site/meto/suite_config.cylc") %} [[METO_ORIG]] +{% if site_vars["ex_trustzone"] == "collab" %} + inherit = EX1A_SCRIPTS +{% else %} pre-script = "module load scitools" platform = {{ROSE_ORIG_HOST}} +{% endif %} {# Family for lfric_coupled rivers/ocean 1st step builds #} [[METO_FCM_MAKE]] diff --git a/rose-stem/site/meto/variables.cylc b/rose-stem/site/meto/variables.cylc index 41a935e6f..b3a417fd2 100644 --- a/rose-stem/site/meto/variables.cylc +++ b/rose-stem/site/meto/variables.cylc @@ -32,9 +32,24 @@ {% do site_vars.update({"site_platforms": ["ex1a", "azspice"]}) %} +{# Settings for EX Collab Zone #} +{% from "socket" import getfqdn %} +{% set hostname = getfqdn() %} +{% if "collab.sc" in hostname %} + {% do site_vars.update({"ex_trustzone": "collab"}) %} + {% do site_vars.update({"USE_TOKENS": true}) %} +{% else %} + {% do site_vars.update({"ex_trustzone": "research"}) %} +{% endif %} + +{% if site_vars["ex_trustzone"] == "collab" %} + {% do site_vars.update({"launch_platform": "ex1a"}) %} + {% do site_vars.update({"scripts_platform": "ex1a"}) %} +{% else %} + {% do site_vars.update({"launch_platform": "azspice"}) %} + {% do site_vars.update({"scripts_platform": "azspice"}) %} +{% endif %} -{% do site_vars.update({"launch_platform": "azspice"}) %} -{% do site_vars.update({"scripts_platform": "azspice"}) %} {% do site_vars.update({"coupled_fcm_make_platform": "azspice"}) %} {% do site_vars.update({"git_mirror_loc": "/data/users/gitassist/git_mirrors"}) %} @@ -42,8 +57,12 @@ {% do site_vars.update({"mesh_build": {"ex1a": "gnu_fast-debug-64bit", "azspice": "gnu_fast-debug-64bit"} }) %} +{% do site_vars.update({"remote_init_family": {"ex1a": "EX1A_REMOTE_INIT"} }) %} + {# Choose EX Host - default to random ab or cd #} -{% if USE_EXZ is defined and USE_EXZ %} +{% if site_vars["ex_trustzone"] == "collab" %} + {% do site_vars.update({"host_ex" : "ex"}) %} +{% elif USE_EXZ is defined and USE_EXZ %} {% do site_vars.update({"host_ex" : "exz"}) %} {% elif USE_EXAB is defined and USE_EXAB %} {% do site_vars.update({"host_ex": "exab"}) %} @@ -60,6 +79,19 @@ {% endif %} {% do LOG.info("Host EX: " + site_vars.host_ex) %} +{# Set node type target #} +{% if USE_GENOA is defined and USE_GENOA %} + {% do site_vars.update({"node_type": "genoa"}) %} + {% do site_vars.update({"node_cores": 192 }) %} + {% do site_vars.update({"node_mem": 720}) %} + {% do site_vars.update({"crayhost": ":crayhost=exb"}) %} +{% else %} + {% do site_vars.update({"node_type": "milan"}) %} + {% do site_vars.update({"node_cores": 128 }) %} + {% do site_vars.update({"node_mem": 238}) %} + {% do site_vars.update({"crayhost": ""}) %} +{% endif %} + {% do site_vars.update({"lfricinputs_kgo_base": "$UMDIR/standard_jobs/lfricinputs/kgo"}) %} {# Set fixed release version the KGO corresponds to #} diff --git a/rose-stem/site/ncas/groups/groups_lfric_atm.cylc b/rose-stem/site/ncas/groups/groups_lfric_atm.cylc index a5e6eefdd..b84ccb279 100644 --- a/rose-stem/site/ncas/groups/groups_lfric_atm.cylc +++ b/rose-stem/site/ncas/groups/groups_lfric_atm.cylc @@ -3,40 +3,40 @@ "lfric_atm_nwp_archer2": [ "lfric_atm_nwp_gal9-C48_MG_ex_gnu_full-debug-64bit", "lfric_atm_nwp_gal9-C48_MG_ex_gnu_production-64bit", - "lfric_atm_nwp_gal9_noukca_3n_1T-C192_MG_ex_gnu_production-64bit", + "lfric_atm_nwp_gal9_3n_1T-C192_MG_ex_gnu_production-64bit", ], "archer2_omp_developer": [ "archer2_omp_developer_cce", "archer2_omp_developer_gnu", ], "archer2_omp_developer_cce": [ - "lfric_atm_nwp_gal9_noukca_1T-C12_ex_cce_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_2T-C12_ex_cce_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex_cce_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex_cce_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex_cce_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_3n_1T-C192_MG_ex_cce_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_3n_2T-C192_MG_ex_cce_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_3n_4T-C192_MG_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_1T-C12_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_2T-C12_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_1T-C48_MG_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_2T-C48_MG_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_4T-C48_MG_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_3n_1T-C192_MG_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_3n_2T-C192_MG_ex_cce_fast-debug-64bit", + "lfric_atm_nwp_gal9_3n_4T-C192_MG_ex_cce_fast-debug-64bit", ], "archer2_omp_developer_gnu": [ - "lfric_atm_nwp_gal9_noukca_1T-C12_ex_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_2T-C12_ex_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_1T-C48_MG_ex_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_2T-C48_MG_ex_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_4T-C48_MG_ex_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_3n_1T-C192_MG_ex_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_3n_2T-C192_MG_ex_gnu_fast-debug-64bit", - "lfric_atm_nwp_gal9_noukca_3n_4T-C192_MG_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_1T-C12_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_2T-C12_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_1T-C48_MG_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_2T-C48_MG_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_4T-C48_MG_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_3n_1T-C192_MG_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_3n_2T-C192_MG_ex_gnu_fast-debug-64bit", + "lfric_atm_nwp_gal9_3n_4T-C192_MG_ex_gnu_fast-debug-64bit", ], "lfric_atm_nwp_quick": [ "lfric_atm_nwp_gal9-C48_MG_ex_gnu_full-debug-64bit", ], "lfric_atm_c192_gnu": [ - "lfric_atm_nwp_gal9_noukca_3n_1T-C192_MG_ex_gnu_production-64bit-rbl32", + "lfric_atm_nwp_gal9_3n_1T-C192_MG_ex_gnu_production-64bit-rbl32", ], "lfric_atm_c192_cce": [ - "lfric_atm_nwp_gal9_noukca_3n_1T-C192_MG_ex_cce_production-64bit-rbl32", + "lfric_atm_nwp_gal9_3n_1T-C192_MG_ex_cce_production-64bit-rbl32", ], "lfric_atm_c192": [ "lfric_atm_c192_gnu", diff --git a/rose-stem/site/ncas/lfric_atm/tasks_lfric_atm.cylc b/rose-stem/site/ncas/lfric_atm/tasks_lfric_atm.cylc index 1e932371b..eaf392cd0 100644 --- a/rose-stem/site/ncas/lfric_atm/tasks_lfric_atm.cylc +++ b/rose-stem/site/ncas/lfric_atm/tasks_lfric_atm.cylc @@ -1,6 +1,6 @@ {% do LOG.debug("Started in site/ncas/lfric_atm/tasks_lfric_atm.cylc") %} -{% if task_ns.conf_name == "nwp_gal9_noukca_3n_1T-C192_MG" %} +{% if task_ns.conf_name == "nwp_gal9_3n_1T-C192_MG" %} {% do task_dict.update({ "xios_nodes": 4, @@ -31,47 +31,47 @@ "plot_str": "", }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_1T-C12" %} +{% elif task_ns.conf_name == "nwp_gal9_1T-C12" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_1T-C12" %} +{% elif task_ns.conf_name == "nwp_gal9_1T-C12" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_2T-C12" %} +{% elif task_ns.conf_name == "nwp_gal9_2T-C12" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_1T-C48_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_1T-C48_MG" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_2T-C48_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_2T-C48_MG" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_4T-C48_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_4T-C48_MG" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_3n_1T-C192_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_3n_1T-C192_MG" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_3n_2T-C192_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_3n_2T-C192_MG" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} -{% elif task_ns.conf_name == "nwp_gal9_mgnoukca_3n_4T-C192_MG" %} +{% elif task_ns.conf_name == "nwp_gal9_3n_4T-C192_MG" %} {% do task_dict.update({ "kgo_checks": 'None' }) %} diff --git a/rose-stem/site/nci/common/suite_config_gadi.cylc b/rose-stem/site/nci/common/suite_config_gadi.cylc index adf8a4fe0..d921dc62d 100644 --- a/rose-stem/site/nci/common/suite_config_gadi.cylc +++ b/rose-stem/site/nci/common/suite_config_gadi.cylc @@ -1,8 +1,14 @@ -{% set gadi_base = 'module load /g/data/access/ngm/modules/envs/lfric/202510/oneapi-openmpi' %} +{% set gadi_base = 'module load /g/data/access/ngm/modules/envs/lfric/202603/oneapi-openmpi' %} {% set gadi_base_coupled = 'module load /g/data/access/ngm/modules/envs/lfric-coupled/202511/oneapi-openmpi' %} {% set gadi_plot = 'module load /g/data/access/ngm/modules/analysis3/21.10' %} +[scheduler] + [[events]] + # Load newer python to run handlers + shutdown handlers = "module load /g/data/access/ngm/modules/envs/lfric/202603/oneapi-openmpi; envrun suite_report_git.py -S $CYLC_WORKFLOW_RUN_DIR" + stall handlers = "module load /g/data/access/ngm/modules/envs/lfric/202603/oneapi-openmpi; envrun suite_report_git.py -S $CYLC_WORKFLOW_RUN_DIR" + [runtime] [[GADI_BASE]] platform=gadi @@ -79,12 +85,17 @@ [[GADI_EXPORT-SOURCE]] platform=localhost pre-script="module load python3/3.12.1" - post-script="sed -i -e 's/FFLAGS_WARNINGS = -warn all -warn errors -gen-interfaces nosource/FFLAGS_WARNINGS = -warn all -gen-interfaces nosource/' $SOURCE_ROOT/lfric_core/infrastructure/build/fortran/ifort.mk" [[[environment]]] hostname = 'gadi.nci.org.au' SITE = 'nci' PLATFORM_SYNC = false + [[export-source]] + pre-script=""" + module load python3/3.12.1 + module load python3-as-python + """ + [[GADI_SCRIPTS]] inherit=GADI_BASE diff --git a/rose-stem/site/uoe/common/default_directives.cylc b/rose-stem/site/uoe/common/default_directives.cylc index b7242f30f..f595a0f8b 100644 --- a/rose-stem/site/uoe/common/default_directives.cylc +++ b/rose-stem/site/uoe/common/default_directives.cylc @@ -23,6 +23,9 @@ "tech-tests_memory": [1, "GB"], "tech-tests_cpus": 1, }, + "lfric_atm": { + "wallclock": 39, + }, }, "epic": { "memory": [50, "GB"], @@ -41,8 +44,11 @@ "tech-tests_memory": [6, "GB"], "tech-tests_cpus": 1, }, + "lfric_atm": { + "wallclock": 39, + }, }, }) %} -{% do LOG.debug("Finished in site/meto/common/default_directives.cylc") %} \ No newline at end of file +{% do LOG.debug("Finished in site/meto/common/default_directives.cylc") %} diff --git a/rose-stem/templates/common_macros.cylc b/rose-stem/templates/common_macros.cylc index ed9efabee..9d166a54b 100644 --- a/rose-stem/templates/common_macros.cylc +++ b/rose-stem/templates/common_macros.cylc @@ -169,7 +169,7 @@ {# Remove a task prefix if listed above #} {% for prefix in task_prefixes %} {% if ns.str.startswith(prefix) %} - {% set ns.str = ns.str|replace(prefix~"_", "") %} + {% set ns.str = ns.str|replace(prefix~"_", "", 1) %} {% endif %} {% endfor %} diff --git a/rose-stem/templates/default_task_definitions.cylc b/rose-stem/templates/default_task_definitions.cylc index be9cabd69..93f479a55 100644 --- a/rose-stem/templates/default_task_definitions.cylc +++ b/rose-stem/templates/default_task_definitions.cylc @@ -234,4 +234,12 @@ {% do task_dict.update({"rose_ana_families": [task_ns.platform|upper~"_ROSE_ANA"]}) %} {% endif %} +{# ###################################### #} +{# MPI & LibFabric Configuration Settings #} +{# ###################################### #} + +{% if "CXI_MATCH_hybrid" not in task_dict %} + {% do task_dict.update({"CXI_MATCH_hybrid": false}) %} +{% endif %} + {% do LOG.debug("Finished in templates/default_task_definitions.cylc") %} diff --git a/rose-stem/templates/graph/generate_graph.cylc b/rose-stem/templates/graph/generate_graph.cylc index 7b4ad585b..ea6f81e7b 100644 --- a/rose-stem/templates/graph/generate_graph.cylc +++ b/rose-stem/templates/graph/generate_graph.cylc @@ -59,11 +59,6 @@ "graph file.") }} {% endif %} - {% elif task_ns.application == "lfricinputs" %} - - {# lfricinputs graphs are different due to building from fcm_make #} - {% include "templates/graph/populate_graph_lfricinputs.cylc" %} - {% else %} {# Otherwise populate the graph using the templating #} diff --git a/rose-stem/templates/graph/populate_graph_lfricinputs.cylc b/rose-stem/templates/graph/populate_graph_lfricinputs.cylc deleted file mode 100644 index e0427acc2..000000000 --- a/rose-stem/templates/graph/populate_graph_lfricinputs.cylc +++ /dev/null @@ -1,121 +0,0 @@ -{# ########################################################################### #} -{# (c) Crown copyright 2024 Met Office. All rights reserved. #} -{# The file LICENCE, distributed with this code, contains details of the terms #} -{# under which the code may be used. #} -{# ########################################################################### #} -{% do LOG.debug("Entered templates/graph/populate_graph_lfricinputs.cylc") %} -{% do LOG.debug("Task: "~task) %} - -{# Define the graph for this task assuming it's an lfricinputs task #} - -{# ######################################### #} -{# Set Task Names for any that need defining #} -{# ######################################### #} - -{# String required by all build steps #} -{% set build_string = task_ns.application~"_"~ - task_values["app_name"]~"_"~ - task_ns.platform~"_"~ - task_ns.compiler~"_"~ - task_ns.extras %} - -{# Set export source task #} -{% set export_task = "export-source => export-source_"~task_ns.platform %} -{% if "export-source" not in tasks_to_run %} - {% do tasks_to_run.update({"export-source": {} }) %} -{% endif %} -{% if "export-source_"~task_ns.platform not in tasks_to_run %} - {% do tasks_to_run.update({"export-source_"~task_ns.platform: {} }) %} -{% endif %} - -{# Set task_names and populate tasks_to_run #} -{% set build_task = "build_"~build_string %} -{% if build_task not in tasks_to_run %} - {% do tasks_to_run.update({build_task: task_values}) %} -{% endif %} - - -{# Work out if we need to define a mesh generation task #} -{# Don't do it if this is a build task #} -{# Otherwise force all inputs tasks to generate meshes #} -{% set build_only = false %} -{% if task.startswith("build") %} - {% set build_only = true %} -{% endif %} - -{# Don't run the application if this is a build task #} -{% if not build_only %} - {% set application_run_task = "run_"~ - task_ns.application~"_"~ - task_ns.conf_name~"_"~ - task_ns.platform~"_"~ - task_ns.compiler~"_"~ - task_ns.extras %} - {% if application_run_task not in tasks_to_run %} - {% do tasks_to_run.update({application_run_task: task_values}) %} - {% endif %} - - {% set rose_ana_task = "rose_ana_"~ - task_ns.application~"_"~ - task_ns.conf_name~"_"~ - task_ns.platform~"_"~ - task_ns.compiler~"_"~ - task_ns.extras %} - {% if rose_ana_task not in tasks_to_run %} - {% do tasks_to_run.update({rose_ana_task: task_values}) %} - {% endif %} - - {# Set mesh build task #} - {% set mesh_build_task = "build_mesh_"~ - task_ns.platform~"_"~ - site_vars["mesh_build"][task_ns.platform] %} - {% if mesh_build_task not in tasks_to_run %} - {% do tasks_to_run.update({mesh_build_task: {} }) %} - {% endif %} - - {# Set mesh generation task #} - {% set mesh_run_task = "run_mesh_"~ - task_values["resolution"]~"_"~ - task_ns.platform~"_"~ - site_vars["mesh_build"][task_ns.platform] %} - {% if mesh_run_task not in tasks_to_run %} - {% do tasks_to_run.update({mesh_run_task: {} }) %} - {% endif %} -{% endif %} - - -{# ################ #} -{# Create the Graph #} -{# ################ #} - -{% do graph_sections.append([ - export_task, build_task - ]) %} - -{# Don't run the application if this is a build task #} -{# Dont run the application if building with cray fortran #} -{% if not build_only and "crayftn" not in task_ns.compiler %} - {% do graph_sections.append([ - export_task, mesh_build_task - ]) %} - {% do graph_sections.append([ - mesh_build_task, mesh_run_task - ]) %} - {% do graph_sections.append([ - mesh_run_task, application_run_task - ]) %} - - {% do graph_sections.append([ - build_task, application_run_task - ]) %} - {% do graph_sections.append([ - application_run_task, rose_ana_task - ]) %} - - {# Populate the graph for generating weights if not a scintelapi task #} - {% if "scintelapi" not in task_ns.conf_name %} - {% include "templates/graph/populate_gen_weights_graph.cylc" %} - {% endif %} -{% endif %} - -{% do LOG.debug("Finished in templates/graph/populate_graph_lfricinputs.cylc") %} diff --git a/rose-stem/templates/graph/populate_graph_sections.cylc b/rose-stem/templates/graph/populate_graph_sections.cylc index b16d498af..7b919c1c6 100644 --- a/rose-stem/templates/graph/populate_graph_sections.cylc +++ b/rose-stem/templates/graph/populate_graph_sections.cylc @@ -21,6 +21,11 @@ {% else %} {% set checksum_kgo = false %} {% endif %} +{% if "rose_ana" in task_values["kgo_checks"] %} + {% set rose_ana_kgo = true %} +{% else %} + {% set rose_ana_kgo = false %} +{% endif %} {% if "fields" in task_values["kgo_checks"] %} {% set fields_kgo = true %} {% else %} @@ -96,10 +101,18 @@ {# Do we need to build an application? #} {# mesh builds covered above and everything else needs a build #} {% if task_ns.application != "mesh" %} - {% set application_build_task = "build_"~ - task_ns.application~"_"~ - task_ns.platform~"_"~ - task_values["build_conf"] %} + {% if task_ns.application == "lfricinputs" %} + {% set application_build_task = "build_"~ + task_ns.application~"_"~ + task_values["app_name"]~"_"~ + task_ns.platform~"_"~ + task_values["build_conf"] %} + {% else %} + {% set application_build_task = "build_"~ + task_ns.application~"_"~ + task_ns.platform~"_"~ + task_values["build_conf"] %} + {% endif %} {# If the task is the application build task then use the task dictionary #} {# Otherwise use an empty dict to be populated later #} {% if application_build_task not in tasks_to_run %} @@ -210,7 +223,20 @@ application_run_task, checksum_task~"?"]) %} {% endif %} - + {% if rose_ana_kgo %} + {% set rose_ana_task = "rose_ana_"~ + task_ns.application~"_"~ + task_ns.conf_name~"_"~ + task_ns.platform~"_"~ + task_ns.compiler~"_"~ + task_ns.extras %} + {% if rose_ana_task not in tasks_to_run %} + {% do tasks_to_run.update({rose_ana_task: task_values}) %} + {% endif %} + {% do graph_sections.append([ + application_run_task, rose_ana_task + ]) %} + {% endif %} {% if plot %} {% set plot_task = "plot_"~ task_ns.application~"_"~ @@ -273,8 +299,9 @@ {% include "templates/graph/populate_graph_lfric_coupled.cylc" %} {% endif %} -{# lfric2lfric graphs require generate_weights tasks before the application run #} -{% if task_ns.application == "lfric2lfric" and task_ns.conf_name.startswith("oasis") %} +{# lfric2lfric, lfric2um, and um2lfric graphs require generate_weights tasks before the application run #} +{% if (task_ns.application == "lfric2lfric" and task_ns.conf_name.startswith("oasis")) or + (task_ns.application == "lfricinputs" and ("scintelapi" not in task_ns.conf_name)) %} {% include "templates/graph/populate_gen_weights_graph.cylc" %} {% endif %} diff --git a/rose-stem/templates/runtime/generate_runtime_application.cylc b/rose-stem/templates/runtime/generate_runtime_application.cylc index d7a2406b4..b9e507f15 100644 --- a/rose-stem/templates/runtime/generate_runtime_application.cylc +++ b/rose-stem/templates/runtime/generate_runtime_application.cylc @@ -71,7 +71,8 @@ 'echo $RELATIVE_LOG_ROOT > $TASK_OUTPUT_DIR/run.log.path', 'find . -regex ".*PET0+\..+\.Log" -exec cp {} $ROSE_TASK_LOG_DIR \;', 'find . -regex ".*PET0+\..+\.Log" -exec cp {} $TASK_OUTPUT_DIR \;', - 'find . -regex ".*PET0+\..+\.Log" -exec cat {} \;', + 'ls -sh $TASK_OUTPUT_DIR/results > $ROSE_TASK_LOG_DIR/results_file_sizes.log', + 'find . -name timer.txt -exec cp {} $ROSE_TASK_LOG_DIR \;', 'test -f '~task_values["app_name"]~ '-checksums.txt && cp $CYLC_TASK_WORK_DIR/'~ task_values["app_name"]~'-checksums.txt $TASK_OUTPUT_DIR/checksum.txt', @@ -144,6 +145,11 @@ {% if "memory_plot_ex" in task_values %} MEMORY_PROFILE = {{task_values["memory_plot_ex"]}} {% endif %} +{% if SITE~"-"~task_ns.platform == 'meto-ex1a' %} + {% if "CXI_MATCH_hybrid" in task_values and task_values["CXI_MATCH_hybrid"] %} + FI_CXI_RX_MATCH_MODE = "hybrid" + {% endif %} +{% endif %} {% if task_ns.application == "lfricinputs" %} {% include "templates/runtime/lfricinputs_task_environment.cylc" %} diff --git a/rose-stem/templates/runtime/generate_runtime_control.cylc b/rose-stem/templates/runtime/generate_runtime_control.cylc index e900d6d8e..00a04b699 100644 --- a/rose-stem/templates/runtime/generate_runtime_control.cylc +++ b/rose-stem/templates/runtime/generate_runtime_control.cylc @@ -24,7 +24,7 @@ ROSE_TASK_APP = extract_source DEPENDENCIES = {{dependencies}} USE_MIRRORS = {{USE_MIRRORS}} - USE_TOKENS = {{USE_TOKENS}} + USE_TOKENS = {{site_vars.get("USE_TOKENS", "false")}} {% if USE_MIRRORS %} {% if "git_mirror_loc" in site_vars %} GIT_MIRROR_LOC = {{site_vars.git_mirror_loc}} @@ -100,8 +100,14 @@ {% set platform = task.split('_')[1] %} + {% if "remote_init_family" in site_vars and platform in site_vars["remote_init_family"] %} + {% set remote_inherit = "EXPORT-SOURCE, "~site_vars["remote_init_family"][platform]~", CONTROL_TASK_RETRIES" %} + {% else %} + {% set remote_inherit = "EXPORT-SOURCE, "~platform|upper~"_BASE, CONTROL_TASK_RETRIES" %} + {% endif %} + [[{{task}}]] - inherit = EXPORT-SOURCE, {{platform|upper}}_BASE, CONTROL_TASK_RETRIES + inherit = {{remote_inherit}} script = true execution time limit = PT1M diff --git a/science/adjoint/patches/kernel/adj_dg_matrix_vector_kernel_mod.patch b/science/adjoint/patches/kernel/adj_dg_matrix_vector_kernel_mod.patch index a2dd2540b..ad1aa671a 100644 --- a/science/adjoint/patches/kernel/adj_dg_matrix_vector_kernel_mod.patch +++ b/science/adjoint/patches/kernel/adj_dg_matrix_vector_kernel_mod.patch @@ -27,3 +27,21 @@ contains subroutine adj_dg_matrix_vector_code_r_single(cell, nlayers, lhs, x, ncell_3d, matrix, ndf1, undf1, map1, ndf2, undf2, map2) +@@ -56,7 +56,7 @@ + do df1 = ndf1, 1, -1 + i1 = map1(df1) + do idx = i1 + nl, i1, -1 +- lhs(idx) = 0.0 ++ lhs(idx) = 0.0_r_single + enddo + enddo + +@@ -97,7 +97,7 @@ + do df1 = ndf1, 1, -1 + i1 = map1(df1) + do idx = i1 + nl, i1, -1 +- lhs(idx) = 0.0 ++ lhs(idx) = 0.0_r_double + enddo + enddo + diff --git a/science/adjoint/patches/kernel/adj_horizontal_mass_flux_kernel_mod.patch b/science/adjoint/patches/kernel/adj_horizontal_mass_flux_kernel_mod.patch new file mode 100644 index 000000000..413969025 --- /dev/null +++ b/science/adjoint/patches/kernel/adj_horizontal_mass_flux_kernel_mod.patch @@ -0,0 +1,11 @@ +@@ -38,9 +38,7 @@ + real(kind=r_tran) :: direction + real(kind=r_tran), dimension(nfaces) :: v_dot_n + +- v_dot_n(:) = 1.0_r_tran +- v_dot_n(1) = -1.00000000000000 +- v_dot_n(nfaces) = -1.00000000000000 ++ v_dot_n = (/ -1.0_r_tran, 1.0_r_tran, 1.0_r_tran, -1.0_r_tran /) + do df = nfaces, 1, -1 + do k = nlayers - 1, 0, -1 + direction = v_dot_n(df) * wind(k + map_w2(df)) diff --git a/science/adjoint/patches/kernel/adj_sci_combine_multidata_field_kernel_mod.patch b/science/adjoint/patches/kernel/adj_sci_combine_multidata_field_kernel_mod.patch index 8a7e31915..766fa6892 100644 --- a/science/adjoint/patches/kernel/adj_sci_combine_multidata_field_kernel_mod.patch +++ b/science/adjoint/patches/kernel/adj_sci_combine_multidata_field_kernel_mod.patch @@ -34,7 +34,78 @@ contains subroutine adj_combine_multidata_field_code_r_single(nlayers, field_out, n, field1_in, n1, field2_in, n2, ndata_first, ndf, & -@@ -133,4 +133,4 @@ +@@ -49,15 +49,15 @@ + + if (ndata_first) then + do k = nlayers - 1, 0, -1 +- ij = k * n + map(1) + ij = k * n + n1 + map(1) + do df = n2 - 1, 0, -1 + field2_in(map_2(1) + k * n2 + df) = field2_in(map_2(1) + k * n2 + df) + field_out(ij + df) +- field_out(ij + df) = 0.0 ++ field_out(ij + df) = 0.0_r_single + enddo ++ ij = k * n + map(1) + do df = n1 - 1, 0, -1 + field1_in(map_1(1) + k * n1 + df) = field1_in(map_1(1) + k * n1 + df) + field_out(ij + df) +- field_out(ij + df) = 0.0 ++ field_out(ij + df) = 0.0_r_single + enddo + enddo + else +@@ -65,14 +65,14 @@ + ij = df * nlayers + n1 * nlayers - nlayers + map(1) + do k = nlayers - 1, 0, -1 + field2_in(map_2(1) + (df - 1) * nlayers + k) = field2_in(map_2(1) + (df - 1) * nlayers + k) + field_out(ij + k) +- field_out(ij + k) = 0.0 ++ field_out(ij + k) = 0.0_r_single + enddo + enddo + do df = n1, 1, -1 + ij = df * nlayers - nlayers + map(1) + do k = nlayers - 1, 0, -1 + field1_in(map_1(1) + (df - 1) * nlayers + k) = field1_in(map_1(1) + (df - 1) * nlayers + k) + field_out(ij + k) +- field_out(ij + k) = 0.0 ++ field_out(ij + k) = 0.0_r_single + enddo + enddo + end if +@@ -103,15 +103,15 @@ + + if (ndata_first) then + do k = nlayers - 1, 0, -1 +- ij = k * n + map(1) + ij = k * n + n1 + map(1) + do df = n2 - 1, 0, -1 + field2_in(map_2(1) + k * n2 + df) = field2_in(map_2(1) + k * n2 + df) + field_out(ij + df) +- field_out(ij + df) = 0.0 ++ field_out(ij + df) = 0.0_r_double + enddo ++ ij = k * n + map(1) + do df = n1 - 1, 0, -1 + field1_in(map_1(1) + k * n1 + df) = field1_in(map_1(1) + k * n1 + df) + field_out(ij + df) +- field_out(ij + df) = 0.0 ++ field_out(ij + df) = 0.0_r_double + enddo + enddo + else +@@ -119,18 +119,18 @@ + ij = df * nlayers + n1 * nlayers - nlayers + map(1) + do k = nlayers - 1, 0, -1 + field2_in(map_2(1) + (df - 1) * nlayers + k) = field2_in(map_2(1) + (df - 1) * nlayers + k) + field_out(ij + k) +- field_out(ij + k) = 0.0 ++ field_out(ij + k) = 0.0_r_double + enddo + enddo + do df = n1, 1, -1 + ij = df * nlayers - nlayers + map(1) + do k = nlayers - 1, 0, -1 + field1_in(map_1(1) + (df - 1) * nlayers + k) = field1_in(map_1(1) + (df - 1) * nlayers + k) + field_out(ij + k) +- field_out(ij + k) = 0.0 ++ field_out(ij + k) = 0.0_r_double + enddo + enddo + end if end subroutine adj_combine_multidata_field_code_r_double diff --git a/science/adjoint/patches/kernel/adj_w3v_advective_update_kernel_mod.patch b/science/adjoint/patches/kernel/adj_w3v_advective_update_kernel_mod.patch new file mode 100644 index 000000000..350fd6032 --- /dev/null +++ b/science/adjoint/patches/kernel/adj_w3v_advective_update_kernel_mod.patch @@ -0,0 +1,42 @@ +@@ -45,12 +45,7 @@ + integer(kind=i_def) :: offset + real(kind=r_tran) :: w + real(kind=r_tran) :: dtdz +- real(kind=r_tran) :: t_u +- real(kind=r_tran) :: t_d + +- dtdz = 0.0_r_tran +- t_u = 0.0_r_tran +- t_d = 0.0_r_tran + if (ndf_w2 == 2) then + df = 1 + offset = 0 +@@ -61,23 +56,16 @@ + do k = nlayers - 1, 0, -1 + w = 0.5 * wind(k + map_w2(df)) + 0.5 * wind(k + map_w2(df) + 1) + ik = cell * nlayers + k - nlayers + 1 +- dtdz = dtdz + advective_increment(map_w3(1) + k) * w * REAL(m3_inv(ik,1,1), r_tran) +- t_d = t_d + (-dtdz) +- t_u = t_u + dtdz +- dtdz = 0.0 ++ dtdz = advective_increment(map_w3(1) + k) * w * REAL(m3_inv(ik,1,1), r_tran) + if (w <= 0.0_r_tran .AND. k < nlayers - 1) then +- tracer(map_md(1) + offset + k + 1) = tracer(map_md(1) + offset + k + 1) + t_u +- t_u = 0.0 ++ tracer(map_md(1) + offset + k + 1) = tracer(map_md(1) + offset + k + 1) + dtdz + else +- tracer(map_md(1) + offset + nlayers + k) = tracer(map_md(1) + offset + nlayers + k) + t_u +- t_u = 0.0 ++ tracer(map_md(1) + offset + nlayers + k) = tracer(map_md(1) + offset + nlayers + k) + dtdz + end if + if (w > 0.0_r_tran .AND. k > 0) then +- tracer(map_md(1) + offset + nlayers + k - 1) = tracer(map_md(1) + offset + nlayers + k - 1) + t_d +- t_d = 0.0 ++ tracer(map_md(1) + offset + nlayers + k - 1) = tracer(map_md(1) + offset + nlayers + k - 1) - dtdz + else +- tracer(map_md(1) + offset + k) = tracer(map_md(1) + offset + k) + t_d +- t_d = 0.0 ++ tracer(map_md(1) + offset + k) = tracer(map_md(1) + offset + k) - dtdz + end if + enddo + diff --git a/science/adjoint/patches/kernel/atl_horizontal_mass_flux_kernel_mod.patch b/science/adjoint/patches/kernel/atl_horizontal_mass_flux_kernel_mod.patch index 9e6a07c05..aa04ceb40 100644 --- a/science/adjoint/patches/kernel/atl_horizontal_mass_flux_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_horizontal_mass_flux_kernel_mod.patch @@ -8,7 +8,7 @@ - type, public, extends(kernel_type) :: adj_horizontal_mass_flux_kernel_type + type, public, extends(kernel_type) :: atl_horizontal_mass_flux_kernel_type type(ARG_TYPE) :: META_ARGS(4) = (/ & - arg_type(gh_field, gh_real, gh_inc, any_w2), & + arg_type(gh_field, gh_real, gh_read, any_w2), & arg_type(gh_field, gh_real, gh_read, any_w2), & @@ -11,15 +11,15 @@ arg_type(gh_field, gh_real, gh_read, any_discontinuous_space_1)/) @@ -30,7 +30,18 @@ &undf_md, map_md) integer(kind=i_def), parameter :: nfaces = 4 integer(kind=i_def), intent(in) :: nlayers -@@ -53,6 +53,6 @@ +@@ -39,9 +39,7 @@ + real(kind=r_def) :: direction + real(kind=r_def), dimension(nfaces) :: v_dot_n + +- v_dot_n(:) = 1.0_r_def +- v_dot_n(1) = -1.00000000000000 +- v_dot_n(nfaces) = -1.00000000000000 ++ v_dot_n = (/ -1.0_r_def, 1.0_r_def, 1.0_r_def, -1.0_r_def /) + do df = nfaces, 1, -1 + do k = nlayers - 1, 0, -1 + direction = ls_wind(k + map_w2(df)) * v_dot_n(df) +@@ -52,6 +50,6 @@ enddo enddo diff --git a/science/adjoint/patches/kernel/atl_kinetic_energy_gradient_kernel_mod.patch b/science/adjoint/patches/kernel/atl_kinetic_energy_gradient_kernel_mod.patch index c82ba1b0d..78961208c 100644 --- a/science/adjoint/patches/kernel/atl_kinetic_energy_gradient_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_kinetic_energy_gradient_kernel_mod.patch @@ -1,18 +1,19 @@ -@@ -1,11 +1,11 @@ +@@ -1,4 +1,4 @@ -module adj_kinetic_energy_gradient_kernel_mod +module atl_kinetic_energy_gradient_kernel_mod use argument_mod, only : any_discontinuous_space_3, any_space_9, arg_type, cell_column, func_type, gh_basis, gh_diff_basis, & &gh_field, gh_inc, gh_quadrature_xyoz, gh_read, gh_real use constants_mod, only : i_def, r_def - use fs_continuity_mod, only : w2 - use kernel_mod, only : kernel_type +@@ -8,7 +8,7 @@ + use finite_element_config_mod, only : coord_system + use planet_config_mod, only : scaled_radius implicit none - type, public, extends(kernel_type) :: adj_kinetic_energy_gradient_kernel_type + type, public, extends(kernel_type) :: atl_kinetic_energy_gradient_kernel_type type(ARG_TYPE) :: META_ARGS(5) = (/ & arg_type(gh_field, gh_real, gh_read, w2), & arg_type(gh_field, gh_real, gh_inc, w2), & -@@ -18,15 +18,15 @@ +@@ -21,15 +21,15 @@ INTEGER :: GH_SHAPE = gh_quadrature_xyoz INTEGER :: OPERATES_ON = cell_column CONTAINS @@ -32,7 +33,7 @@ &w2_basis, w2_diff_basis, ndf_chi, undf_chi, map_chi, chi_basis, chi_diff_basis, ndf_pid, undf_pid, map_pid, nqp_h, nqp_v, wqp_h, & &wqp_v) use sci_coordinate_jacobian_mod, only : coordinate_jacobian -@@ -75,7 +75,6 @@ +@@ -78,7 +78,6 @@ real(kind=r_def) :: dv real(kind=r_def), dimension(3) :: mul1 real(kind=r_def), dimension(3) :: mul2 @@ -40,7 +41,7 @@ real(kind=r_def) :: res_dot_product integer :: idx integer :: idx_1 -@@ -153,6 +152,6 @@ +@@ -156,6 +155,6 @@ enddo enddo diff --git a/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch b/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch index 7d5737dd7..fec1840cf 100644 --- a/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_poly1d_vert_adv_kernel_mod.patch @@ -33,64 +33,156 @@ &ndf_wt, undf_wt, map_wt, ndf_w2v, undf_w2v, map_w2v, ndf_c, undf_c, map_c) integer(kind=i_def), intent(in) :: nlayers integer(kind=i_def), intent(in) :: ndf_wt -@@ -61,7 +61,6 @@ +@@ -61,75 +61,96 @@ real(kind=r_def) :: dpdz real(kind=r_def) :: ls_dpdz real(kind=r_def) :: safe_ls_tracer - real(kind=r_def) :: eps real(kind=r_def), dimension(0:nlayers) :: ls_log_tracer - real(kind=r_def) :: tmp1 - real(kind=r_def) :: tmp2 -@@ -84,7 +83,7 @@ - itmp3 = FLOOR(tmp2) - stencil(p + 1) = -itmp3 + k + p - enddo +- real(kind=r_def) :: tmp1 +- real(kind=r_def) :: tmp2 +- integer(kind=i_def) :: i +- integer(kind=i_def) :: itmp3 + +- dpdz = 0.0_r_def + ij = map_wt(1) +- if (logspace) then +- do k = 0, nlayers, 1 +- ls_log_tracer(k) = LOG(MAX(eps, ABS(ls_tracer(ij + k)))) +- enddo ++ ++ ! For logspace the nonlinear term is: ++ ! dp_{j}/dz = p_j * sum_i a_i * log( p_i) ++ ! The tl term is then: ++ ! dp_{j}/dz = ls_p_j * sum_i a_i * p_i / ls_p_i ! ++ ! + p_j * sum_i a_i * log( ls_p_i ) ++ ++ ! Compute log of tracer. This code should only be used for a positive ++ ! quantity, but adding in the abs ensures no errors are thrown ++ ! if negative numbers are passed through in redundant calculations ++ ! in the halos ++ if ( logspace ) then ++ do k = 0, nlayers ++ ls_log_tracer(k) = log(max(EPS,abs(ls_tracer(ij+k)))) ++ end do + end if +- vertical_order = MIN(global_order, nlayers - 1) +- use_upwind = MOD(vertical_order, 2) ++ ++ ! Ensure that we reduce the order if there are only a few layers ++ vertical_order = min(global_order, nlayers-1) ++ ++ ! If order is odd then we are using an upwind stencil -> use_upwind = 1 ++ ! For even orders it is zero ++ use_upwind = mod(vertical_order, 2_i_def) ++ ++ ! Compute dtracer/dz using precomputed weights + do k = nlayers - 1, 1, -1 +- do p = 0, vertical_order, 1 +- tmp1 = REAL(vertical_order, r_def) +- tmp2 = 0.5 * tmp1 +- itmp3 = FLOOR(tmp2) +- stencil(p + 1) = -itmp3 + k + p +- enddo - upwind = INT(0.5 * SIGN(1.0, ls_wind(k + map_w2v(1))) + 0.5, i_def) -+ upwind = INT(0.5_r_def * SIGN(1.0_r_def, ls_wind(k + map_w2v(1))) + 0.5_r_def, i_def) - upwind_offset = upwind * use_upwind - stencil = stencil - upwind_offset - kmin = stencil(1) -@@ -106,30 +105,41 @@ - if (kmax > 0) then - stencil = -kmax + stencil - end if +- upwind_offset = upwind * use_upwind +- stencil(:) = -upwind_offset + stencil(:) +- kmin = stencil(1) +- do i = 2, vertical_order + 1, 1 +- if (stencil(i) < kmin) then +- kmin = stencil(i) +- end if +- enddo +- if (kmin < 0) then +- stencil(:) = -kmin + stencil(:) +- end if +- kmax = stencil(1) +- do i = 2, vertical_order + 1, 1 +- if (stencil(i) > kmax) then +- kmax = stencil(i) +- end if +- enddo +- kmax = kmax - nlayers +- if (kmax > 0) then +- stencil(:) = -kmax + stencil(:) +- end if ++ ++ ! Compute the stencil of points required ++ do p = 0, vertical_order ++ stencil(p+1) = k - floor(real(vertical_order,r_def)/2.0_r_def) + p ++ end do ++ ++ ! Adjust the stencil based upon the wind sign for upwind (odd order) ++ ! reconstructions only. ++ ! if wind > 0 -> upwind_offset = 1 ++ ! if wind < 0 -> upwind_offset = 0 ++ upwind = int(0.5_r_def*(1.0_r_def + sign(1.0_r_def,ls_wind(map_w2v(1)+k))),i_def) ++ upwind_offset = use_upwind*upwind ++ stencil = stencil - upwind_offset + -+ ! ARP - calculate passive ls_dpdz first. ++ ! Adjust stencil near boundaries to avoid going out of bounds ++ kmin = minval(stencil(1:vertical_order+1)) ++ if ( kmin < 0 ) stencil = stencil - kmin ++ kmax = maxval(stencil(1:vertical_order+1)) - nlayers ++ if ( kmax > 0 ) stencil = stencil - kmax ++ ++ ! Compute the derivative and the advective update ++ dpdz = 0.0_r_def ls_dpdz = 0.0_r_def -+ if (logspace) then -+ do p = vertical_order + 1, 1, -1 +- dpdz = dpdz + advective(map_wt(1) + k) * ls_wind(k + map_w2v(1)) +- wind(k + map_w2v(1)) = wind(k + map_w2v(1)) + ls_dpdz * advective(map_wt(1) + k) +- if (logspace) then +- safe_ls_tracer = SIGN(MAX(eps, ABS(ls_tracer(ij + k))), ls_tracer(ij + k)) +- ls_dpdz = ls_dpdz * safe_ls_tracer +- tracer(ij + k) = tracer(ij + k) + ls_dpdz * dpdz +- dpdz = dpdz * safe_ls_tracer ++ safe_ls_tracer = 1.0_r_def ++ if ( logspace ) then ++ ! dp/dz = p * d(log(p))/dz ++ do p = 1, vertical_order + 1 + ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 + ls_dpdz = ls_dpdz + coeff(ik)*ls_log_tracer(stencil(p)) + end do ++ safe_ls_tracer = sign(max(EPS,abs(ls_tracer(ij + k))), ls_tracer(ij + k)) + else -+ do p = vertical_order + 1, 1, -1 ++ do p = 1, vertical_order + 1 + ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 + ls_dpdz = ls_dpdz + coeff(ik)*ls_tracer(ij + stencil(p)) + end do + end if - dpdz = dpdz + advective(map_wt(1) + k) * ls_wind(k + map_w2v(1)) - wind(k + map_w2v(1)) = wind(k + map_w2v(1)) + ls_dpdz * advective(map_wt(1) + k) + - if (logspace) then - safe_ls_tracer = SIGN(MAX(eps, ABS(ls_tracer(ij + k))), ls_tracer(ij + k)) -- ls_dpdz = ls_dpdz * safe_ls_tracer - tracer(ij + k) = tracer(ij + k) + ls_dpdz * dpdz - dpdz = dpdz * safe_ls_tracer ++ dpdz = dpdz + ls_wind(map_w2v(1)+k) * advective(map_wt(1)+ k) ++ wind(map_w2v(1)+k) = wind(map_w2v(1)+k) + advective(map_wt(1)+ k) * ls_dpdz * safe_ls_tracer ++ ++ if ( logspace ) then ++ ! dp/dz = p * d(log(p))/dz ++ tracer(ij + k) = tracer(ij + k) + dpdz * ls_dpdz ++ dpdz = safe_ls_tracer * dpdz do p = vertical_order + 1, 1, -1 - ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 +- ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 - ls_dpdz = ls_dpdz + coeff(ik) * ls_log_tracer(stencil(p)) - tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz / SIGN(MAX(eps, ABS(ls_tracer(ij + stencil(p)))), & - &ls_tracer(ij + stencil(p))) - enddo +- tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz / SIGN(MAX(eps, ABS(ls_tracer(ij + stencil(p)))), & +-&ls_tracer(ij + stencil(p))) +- enddo ++ ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 ++ tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz / & ++ ! This is a safe version of ls_tracer ++ sign(max(EPS,abs(ls_tracer(ij + stencil(p)))), ls_tracer(ij + stencil(p))) ++ end do ++ else do p = vertical_order + 1, 1, -1 - ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 +- ik = global_order * upwind_offset + k * ndata + p + upwind_offset + map_c(1) - 1 - ls_dpdz = ls_dpdz + coeff(ik) * ls_tracer(ij + stencil(p)) ++ ik = p + upwind_offset*(global_order+1) + k*ndata + map_c(1) - 1 tracer(ij + stencil(p)) = tracer(ij + stencil(p)) + coeff(ik) * dpdz - enddo +- enddo ++ end do end if - dpdz = 0.0 - enddo +- dpdz = 0.0 +- enddo ++ dpdz = 0.0_r_def ++ end do - end subroutine adj_poly1d_vert_adv_code + end subroutine atl_poly1d_vert_adv_code diff --git a/science/adjoint/patches/kernel/atl_project_eos_pressure_kernel_mod.patch b/science/adjoint/patches/kernel/atl_project_eos_pressure_kernel_mod.patch index b4564ee1a..85bcc5536 100644 --- a/science/adjoint/patches/kernel/atl_project_eos_pressure_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_project_eos_pressure_kernel_mod.patch @@ -1,19 +1,22 @@ -@@ -1,11 +1,12 @@ +@@ -1,4 +1,4 @@ -module adj_project_eos_pressure_kernel_mod +module atl_project_eos_pressure_kernel_mod use argument_mod, only : any_discontinuous_space_3, any_space_2, arg_type, cell_column, func_type, gh_basis, gh_diff_basis, & &gh_field, gh_operator, gh_quadrature_xyoz, gh_read, gh_readwrite, gh_real, gh_write use constants_mod, only : i_def, r_def - use fs_continuity_mod, only : w3, wtheta +@@ -6,9 +6,9 @@ use kernel_mod, only : kernel_type -+ use planet_config_mod, only : kappa, rd, p_zero + use base_mesh_config_mod, only : geometry, topology + use finite_element_config_mod, only : coord_system +- use planet_config_mod, only : scaled_radius ++ use planet_config_mod, only : scaled_radius, kappa, rd, p_zero implicit none - type, public, extends(kernel_type) :: adj_project_eos_pressure_kernel_type + type, public, extends(kernel_type) :: atl_project_eos_pressure_kernel_type type(ARG_TYPE) :: META_ARGS(10) = (/ & arg_type(gh_field, gh_real, gh_readwrite, w3), & arg_type(gh_field, gh_real, gh_readwrite, w3), & -@@ -24,15 +25,15 @@ +@@ -27,15 +27,15 @@ INTEGER :: GH_SHAPE = gh_quadrature_xyoz INTEGER :: OPERATES_ON = cell_column CONTAINS @@ -33,7 +36,7 @@ &chi1, chi2, chi3, panel_id, ncell_3d, m3_inv, ndf_w3, undf_w3, map_w3, w3_basis, ndf_wt, undf_wt, map_wt, wt_basis, ndf_chi, & &undf_chi, map_chi, chi_basis, chi_diff_basis, ndf_pid, undf_pid, map_pid, nqp_h, nqp_v, wqp_h, wqp_v) use sci_coordinate_jacobian_mod, only : coordinate_jacobian -@@ -96,9 +97,6 @@ +@@ -99,9 +99,6 @@ real(kind=r_def) :: ls_theta_vd_at_quad real(kind=r_def) :: tmp_ls_exner real(kind=r_def) :: tmp_exner @@ -43,7 +46,7 @@ exner_e = 0.0_r_def exner_at_quad = 0.0_r_def -@@ -176,6 +174,6 @@ +@@ -179,6 +176,6 @@ enddo enddo diff --git a/science/adjoint/patches/kernel/atl_rhs_project_eos_kernel_mod.patch b/science/adjoint/patches/kernel/atl_rhs_project_eos_kernel_mod.patch index 9707453f6..a8d455937 100644 --- a/science/adjoint/patches/kernel/atl_rhs_project_eos_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_rhs_project_eos_kernel_mod.patch @@ -1,18 +1,19 @@ -@@ -1,11 +1,11 @@ +@@ -1,4 +1,4 @@ -module adj_rhs_project_eos_kernel_mod +module atl_rhs_project_eos_kernel_mod use argument_mod, only : any_discontinuous_space_3, any_space_9, arg_type, cell_column, func_type, gh_basis, gh_diff_basis, & &gh_field, gh_quadrature_xyoz, gh_read, gh_readwrite, gh_real, gh_scalar, gh_write use constants_mod, only : i_def, r_def - use fs_continuity_mod, only : w3, wtheta - use kernel_mod, only : kernel_type +@@ -8,7 +8,7 @@ + use finite_element_config_mod, only : coord_system + use planet_config_mod, only : scaled_radius implicit none - type, public, extends(kernel_type) :: adj_rhs_project_eos_kernel_type + type, public, extends(kernel_type) :: atl_rhs_project_eos_kernel_type type(ARG_TYPE) :: META_ARGS(14) = (/ & arg_type(gh_field, gh_real, gh_readwrite, w3), & arg_type(gh_field, gh_real, gh_readwrite, w3), & -@@ -28,15 +28,15 @@ +@@ -31,15 +31,15 @@ INTEGER :: GH_SHAPE = gh_quadrature_xyoz INTEGER :: OPERATES_ON = cell_column CONTAINS @@ -31,8 +32,8 @@ + subroutine atl_rhs_project_eos_code(nlayers, rhs_eos, exner, rho, theta, moist_dyn_gas, ls_exner, ls_rho, ls_theta, & &ls_moist_dyn_gas, chi1, chi2, chi3, panel_id, kappa, rd, p_zero, ndf_w3, undf_w3, map_w3, w3_basis, ndf_wt, undf_wt, map_wt, & &wt_basis, ndf_chi, undf_chi, map_chi, chi_basis, chi_diff_basis, ndf_pid, undf_pid, map_pid, nqp_h, nqp_v, wqp_h, wqp_v) - use coordinate_jacobian_mod, only : coordinate_jacobian -@@ -176,6 +176,6 @@ + use sci_coordinate_jacobian_mod, only : coordinate_jacobian +@@ -179,6 +179,6 @@ enddo enddo diff --git a/science/adjoint/patches/kernel/atl_vorticity_advection_kernel_mod.patch b/science/adjoint/patches/kernel/atl_vorticity_advection_kernel_mod.patch index 2e526c9d8..20441d4ed 100644 --- a/science/adjoint/patches/kernel/atl_vorticity_advection_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_vorticity_advection_kernel_mod.patch @@ -1,4 +1,4 @@ -@@ -1,34 +1,34 @@ +@@ -1,37 +1,37 @@ -module adj_vorticity_advection_kernel_mod +module atl_vorticity_advection_kernel_mod use kernel_mod, only : kernel_type @@ -8,6 +8,9 @@ - use fs_continuity_mod, only : w1, w2, wchi + use fs_continuity_mod, only : w1, w2 use cross_product_mod, only : cross_product + use base_mesh_config_mod, only : geometry, topology + use finite_element_config_mod, only : coord_system + use planet_config_mod, only : scaled_radius implicit none - type, public, extends(kernel_type) :: adj_vorticity_advection_kernel_type + type, public, extends(kernel_type) :: atl_vorticity_advection_kernel_type @@ -41,7 +44,7 @@ &ndf_w2, undf_w2, map_w2, w2_basis, ndf_w1, undf_w1, map_w1, w1_basis, ndf_chi, undf_chi, map_chi, chi_basis, chi_diff_basis, & &ndf_pid, undf_pid, map_pid, nqp_h, nqp_v, wqp_h, wqp_v) use sci_coordinate_jacobian_mod, only : pointwise_coordinate_jacobian, pointwise_coordinate_jacobian_inverse -@@ -86,7 +86,6 @@ +@@ -89,7 +89,6 @@ real(kind=r_def), dimension(3) :: mul2 real(kind=r_def), dimension(3) :: cross_product1 real(kind=r_def), dimension(3) :: cross_product2 @@ -49,7 +52,7 @@ real(kind=r_def) :: res_dot_product integer :: idx integer :: idx_1 -@@ -207,6 +206,6 @@ +@@ -210,6 +209,6 @@ enddo enddo diff --git a/science/adjoint/patches/kernel/atl_w3v_advective_update_kernel_mod.patch b/science/adjoint/patches/kernel/atl_w3v_advective_update_kernel_mod.patch index 5f4d873e9..7cd2087cd 100644 --- a/science/adjoint/patches/kernel/atl_w3v_advective_update_kernel_mod.patch +++ b/science/adjoint/patches/kernel/atl_w3v_advective_update_kernel_mod.patch @@ -32,8 +32,23 @@ &undf_w3, map_w3, ndf_md, undf_md, map_md, ndf_w2, undf_w2, map_w2) integer(kind=i_def), intent(in) :: nlayers integer(kind=i_def), intent(in) :: cell -@@ -79,6 +79,6 @@ - w = 0.0 +@@ -51,7 +51,6 @@ + real(kind=r_def) :: t_u + real(kind=r_def) :: t_d + +- w = 0.0_r_def + if (ndf_w2 == 2) then + df = 1 + offset = 0 +@@ -73,12 +72,11 @@ + end if + dtdz = -t_d + t_u + ik = cell * nlayers + k - nlayers + 1 +- w = w + dtdz * advective_increment(map_w3(1) + k) * m3_inv(ik,1,1) ++ w = dtdz * advective_increment(map_w3(1) + k) * m3_inv(ik,1,1) + wind(k + map_w2(df)) = wind(k + map_w2(df)) + 0.5 * w + wind(k + map_w2(df) + 1) = wind(k + map_w2(df) + 1) + 0.5 * w +- w = 0.0 enddo - end subroutine adj_w3v_advective_update_code diff --git a/science/adjoint/rose-meta/lfric-adjoint/version30_31.py b/science/adjoint/rose-meta/lfric-adjoint/version30_31.py new file mode 100644 index 000000000..b6f447ed7 --- /dev/null +++ b/science/adjoint/rose-meta/lfric-adjoint/version30_31.py @@ -0,0 +1,282 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-adjoint + # Blank Upgrade Macro + return config, self.reports diff --git a/science/adjoint/rose-meta/lfric-adjoint/versions.py b/science/adjoint/rose-meta/lfric-adjoint/versions.py index 152c043d0..01798ad2b 100644 --- a/science/adjoint/rose-meta/lfric-adjoint/versions.py +++ b/science/adjoint/rose-meta/lfric-adjoint/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/science/adjoint/rose-meta/lfric-adjoint/vn3.1/rose-meta.conf b/science/adjoint/rose-meta/lfric-adjoint/vn3.1/rose-meta.conf new file mode 100644 index 000000000..a95b2cf2e --- /dev/null +++ b/science/adjoint/rose-meta/lfric-adjoint/vn3.1/rose-meta.conf @@ -0,0 +1 @@ +import=lfric-linear/vn3.1 diff --git a/science/adjoint/source/algorithm/core_dynamics/atl_rhs_alg_mod.x90 b/science/adjoint/source/algorithm/core_dynamics/atl_rhs_alg_mod.x90 index 0f8148790..b80325d93 100644 --- a/science/adjoint/source/algorithm/core_dynamics/atl_rhs_alg_mod.x90 +++ b/science/adjoint/source/algorithm/core_dynamics/atl_rhs_alg_mod.x90 @@ -42,8 +42,8 @@ module atl_rhs_alg_mod use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type use derived_config_mod, only: bundle_size use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use atl_rhs_project_eos_kernel_mod, only: atl_rhs_project_eos_kernel_type use atl_rhs_sample_eos_kernel_mod, only: atl_rhs_sample_eos_kernel_type use moist_dyn_mod, only: num_moist_factors, gas_law @@ -128,8 +128,9 @@ subroutine atl_rhs_alg(rhs, alpha_dt, base_state, state, moist_dyn, & integer(kind=i_def), parameter :: exner_stencil_depth = 1 type(function_space_type), pointer :: vector_space_w3_ptr type(field_type) :: dummy_w3 + integer(tik) :: id - if ( subroutine_timers ) call timer('atl_rhs_alg') + if ( LPROF ) call start_timing( id, 'atl_dynamics.rhs_alg' ) mesh => base_state(igh_u)%get_mesh() @@ -298,7 +299,7 @@ subroutine atl_rhs_alg(rhs, alpha_dt, base_state, state, moist_dyn, & setval_c( rhs(igh_t), 0.0_r_def ) ) ! End of adjoint - if ( subroutine_timers ) call timer('atl_rhs_alg') + if ( LPROF ) call stop_timing( id, 'atl_dynamics.rhs_alg' ) end subroutine atl_rhs_alg diff --git a/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 new file mode 100644 index 000000000..148ce790f --- /dev/null +++ b/science/adjoint/source/algorithm/linear_physics/atl_bdy_lyr_alg.x90 @@ -0,0 +1,141 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief (Adjoint of) given TL state(igh_u) compute TLM boundary layer increment u_bl_inc +module atl_bdy_lyr_alg_mod + + use constants_mod, only: r_def + use field_collection_mod, only: field_collection_type + use integer_field_mod, only: integer_field_type + use driver_modeldb_mod, only: modeldb_type + use sci_geometric_constants_mod, only: get_height_fe, & + get_face_selector_ew, & + get_face_selector_ns + use sci_fem_constants_mod, only: get_rmultiplicity_fe + use field_mod, only: field_type + use linear_physics_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_d + use timing_mod, only: start_timing, stop_timing, tik, LPROF + use mesh_mod, only: mesh_type + use fs_continuity_mod, only: W2, W3, Wtheta + use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type + use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type + use atl_bl_inc_kernel_mod, only: atl_bl_inc_kernel_type + + implicit none + + private + public :: atl_bdy_lyr_alg + +contains + +!> @brief (Adjoint of) given TL state(igh_u) compute TLM boundary layer increment u_bl_inc +!> @details The stages are: +!> 1. Call tl_compute_qe_kernel_type: from LS, compute coefficients Q, E +!> 2. Call tl_compute_aubu_kernel_type: from Q,E, compute coefficients Auv, Buv_inv +!> 3. Call atl_bl_inc_kernel_type: (adjoint of) from state(igh_u) use coefficients Auv, Buv_inv to compute u_bl_inc +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!> The original code is at https://wwwspice/~frva/VAR/view/var-2022.12.2/doc/PF_bdy_lyr.html +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u_bl_inc TLM boundary layer increment +!> @param[in,out] u The current TL model prognostic u field, state(igh_u) +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] dt The TL model timestep length +subroutine atl_bdy_lyr_alg(modeldb, u_bl_inc, u, ls_state, dt) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u_bl_inc + type(field_type), intent(inout) :: u + type(field_type), target, intent(in) :: ls_state(bundle_size) + real(kind=r_def), intent(in) :: dt + + type(mesh_type), pointer :: mesh + type(field_type), pointer :: height_w2 + type(field_type), pointer :: height_w3 + type(field_type), pointer :: height_wth + type(field_type), pointer :: w2_rmultiplicity + type(integer_field_type), pointer :: face_selector_ew + type(integer_field_type), pointer :: face_selector_ns + + type(field_collection_type), pointer :: ls_fields + type(field_type), pointer :: ls_land_fraction + + ! Coefficients computed from linearisation state + type(field_type) :: Q + type(field_type) :: E + type(field_type) :: auv + type(field_type) :: buv_inv + + integer(kind=tik) :: id + + if (LPROF) call start_timing(id, 'atl_bdy_lyr_alg') + + ls_fields => modeldb%fields%get_field_collection('ls_fields') + call ls_fields%get_field('ls_land_fraction', ls_land_fraction) + + mesh => u%get_mesh() + height_w2 => get_height_fe(W2, mesh%get_id()) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta, mesh%get_id()) + + w2_rmultiplicity => get_rmultiplicity_fe(W2, mesh%get_id()) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + call ls_state(igh_d)%copy_field_properties(Q) + call ls_state(igh_d)%copy_field_properties(E) + + call u%copy_field_properties(auv) + call u%copy_field_properties(buv_inv) + + call invoke(tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, & + height_wth, & + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m)) + + call invoke(tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m)) + + call invoke(atl_bl_inc_kernel_type(u_bl_inc, & + u, & + auv, & + buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m)) + + if (LPROF) call stop_timing(id, 'atl_bdy_lyr_alg') + +end subroutine atl_bdy_lyr_alg + +end module atl_bdy_lyr_alg_mod diff --git a/science/adjoint/source/algorithm/linear_physics/atl_physics_alg.x90 b/science/adjoint/source/algorithm/linear_physics/atl_physics_alg.x90 new file mode 100644 index 000000000..5f93c8940 --- /dev/null +++ b/science/adjoint/source/algorithm/linear_physics/atl_physics_alg.x90 @@ -0,0 +1,148 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Wrapper for adjoint physics code +module atl_physics_alg_mod + + use constants_mod, only: r_def + use driver_modeldb_mod, only: modeldb_type + use field_mod, only: field_type + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_u + use timing_mod, only: start_timing, stop_timing, tik, LPROF + use mesh_mod, only: mesh_type + use fs_continuity_mod, only: W2 + use sci_geometric_constants_mod, only: get_da_at_w2 + use sci_fem_constants_mod, only: get_mass_matrix_fe + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use adj_matrix_vector_kernel_mod, only: adj_matrix_vector_kernel_type + use atl_bdy_lyr_alg_mod, only: atl_bdy_lyr_alg + use sci_mass_matrix_solver_alg_mod, only: mass_matrix_solver_alg + use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle, set_bundle_scalar + use operator_mod, only: operator_type + + implicit none + + private + public :: atl_physics_alg + +contains + +!> @brief Wrapper for adjoint physics code, currently just atl_bdy_lyr_alg +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u The TL model u field to be incremented +!> @param[in,out] state_star TL model prognostic fields for physics calculations +!> @param[in,out] rhs_phys Residuals +!> @param[in] state The current TL model prognostic fields +!> @param[in] rhs_n Residuals +!> @param[in] rhs_np1 Residuals +!> @param[in] rhs_adv Advective terms +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] mesh The current mesh +!> @param[in] dt The TL model timestep length +subroutine atl_physics_alg(modeldb, & + u, & + state_star, & + rhs_phys, & + rhs_np1, & + rhs_n, & + state, & + rhs_adv, & + ls_state, & + mesh, & + dt) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u + type(field_type), intent(inout) :: state_star(bundle_size) + type(field_type), intent(inout) :: rhs_phys(bundle_size) + type(field_type), intent(in) :: state(bundle_size) + type(field_type), intent(in) :: rhs_n(bundle_size) + type(field_type), intent(in) :: rhs_np1(bundle_size) + type(field_type), intent(in) :: rhs_adv(bundle_size) + type(field_type), intent(in) :: ls_state(bundle_size) + type(mesh_type), pointer, intent(in) :: mesh + real(kind=r_def), intent(in) :: dt + + type(field_type) :: u_bl_inc + type(field_type) :: u_bl_inc_flux + type(field_type) :: du + type(field_type) :: u_star + type(field_type) :: u_star_physical + type(field_type) :: rhsu_np1 + + type(operator_type), pointer :: mm_vel + type(field_type), pointer :: dA + + integer(kind=tik) :: id + + if (LPROF) call start_timing(id, 'atl_physics_alg') + + mm_vel => get_mass_matrix_fe(W2, mesh%get_id()) + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) + + call du%initialise( rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) + + call clone_bundle( state, state_star, bundle_size ) + call copy_bundle( state, state_star, bundle_size ) ! Only state_star(igh_u) is used + call set_bundle_scalar( 0.0_r_def, state_star, bundle_size ) + + dA => get_da_at_w2(mesh%get_id()) + + call invoke( setval_c( u_bl_inc_flux, 0.0_r_def ), & + setval_c( u_bl_inc, 0.0_r_def ), & + setval_c( u_star, 0.0_r_def ), & + setval_c( u_star_physical, 0.0_r_def ), & + setval_c( du, 0.0_r_def ), & + setval_c( rhsu_np1, 0.0_r_def ) ) + + call invoke( enforce_bc_kernel_type( rhs_phys(igh_u) ), & + adj_matrix_vector_kernel_type( rhs_phys(igh_u), u_bl_inc_flux, mm_vel ) ) + + call set_bundle_scalar( 0.0_r_def, rhs_phys, bundle_size ) + + ! Adj of u_bl_inc_flux = u_bl_inc * dA + call invoke( inc_x_times_y( u_bl_inc_flux, dA ), & + inc_x_plus_y( u_bl_inc, u_bl_inc_flux ) ) + + call atl_bdy_lyr_alg( modeldb, u_bl_inc, state_star(igh_u), & + ls_state, dt ) + + ! Adj of state_star(igh_u) <- u_star_physical + call invoke( inc_x_plus_y( u_star_physical, state_star(igh_u) ), & + setval_c( state_star(igh_u), 0.0_r_def ) ) + + ! Adj of u_star_physical = u_star / dA + call invoke( inc_x_divideby_y( u_star_physical, dA ), & + inc_x_plus_y( u_star, u_star_physical ) ) + + ! Adj of u_star = du + state(igh_u) + call invoke( inc_X_plus_Y( du, u_star ), & + inc_X_plus_Y( state(igh_u), u_star ) ) + + ! Adj of call mass_matrix_solver_alg(du, rhsu_np1) + call mass_matrix_solver_alg( rhsu_np1, du ) + + ! Adj of inc_X_plus_Y(rhsu_np1, rhs_adv(igh_u)) + call invoke( inc_X_plus_Y( rhs_adv(igh_u), rhsu_np1 ) ) + + ! Adj of rhsu_np1 <- -rhs_np1(igh_u) + rhs_n(igh_u) + call invoke( inc_X_plus_bY( rhs_np1(igh_u), -1.0_r_def, rhsu_np1 ), & + inc_X_plus_Y( rhs_n(igh_u), rhsu_np1 ) ) + + if (LPROF) call stop_timing(id, 'atl_physics_alg') + +end subroutine atl_physics_alg + +end module atl_physics_alg_mod diff --git a/science/adjoint/source/algorithm/lookup/adj_lookup_table_mod.x90 b/science/adjoint/source/algorithm/lookup/adj_lookup_table_mod.x90 index 043b4bfbf..81a16804c 100644 --- a/science/adjoint/source/algorithm/lookup/adj_lookup_table_mod.x90 +++ b/science/adjoint/source/algorithm/lookup/adj_lookup_table_mod.x90 @@ -13,9 +13,6 @@ module adj_lookup_table_mod use function_space_collection_mod, only : function_space_collection use function_space_mod, only : function_space_type use integer_field_mod, only : integer_field_type - use log_mod, only : log_event, & - log_scratch_space, & - LOG_LEVEL_ERROR use mesh_collection_mod, only : mesh_collection use mesh_mod, only : mesh_type diff --git a/science/adjoint/source/algorithm/lookup/solver/adj_solver_lookup_cache_mod.x90 b/science/adjoint/source/algorithm/lookup/solver/adj_solver_lookup_cache_mod.x90 new file mode 100644 index 000000000..e0aa2d9fa --- /dev/null +++ b/science/adjoint/source/algorithm/lookup/solver/adj_solver_lookup_cache_mod.x90 @@ -0,0 +1,162 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +!> @brief Module containing the cached lookup table object. +module adj_solver_lookup_cache_mod + + use adj_lookup_table_mod, only: adj_lookup_table_type + use constants_mod, only: i_def, l_def + use log_mod, only: log_event, & + log_scratch_space, & + LOG_LEVEL_ERROR + + implicit none + + !> @brief Adjoint lookup table cache type. + !> @details Cache containing the lookup tables needed for each stencil kernel, + !> for every combination of function spaces needed. + type, public :: adj_solver_lookup_cache_type + private + + !> Lookup table for adj_apply_helmholtz_operator_kernel. + type(adj_lookup_table_type), allocatable, dimension(:) :: lookup_apply_hho + + !> Number of multigrid levels for lookup_apply_hho. + integer(kind=i_def) :: multigrid_levels = 0_i_def + + !> Flag to state whether or not cache is initialised + logical(kind=l_def) :: is_initialised = .false._l_def + + contains + + procedure, public :: initialise => adj_solver_lookup_cache_init + procedure, public :: get_lookup_apply_hho + procedure, public :: finalise => adj_solver_lookup_cache_final + + end type adj_solver_lookup_cache_type + + contains + + !============================================================================= + !> @brief Initialise the lookup table cache. + !> @param [in,out] self Lookup table cache + !> @param [in] mesh Pointer to mesh + subroutine adj_solver_lookup_cache_init(self, mesh) + + use adj_lookup_table_generators_alg_mod, only: create_lookup_apply_helmholtz_op + use constants_mod, only: r_solver + use finite_element_config_mod, only: element_order_h, & + element_order_v + use formulation_config_mod, only: l_multigrid + use fs_continuity_mod, only: W3 + use function_space_mod, only: function_space_type + use function_space_chain_mod, only: multigrid_function_space_chain + use function_space_collection_mod, only: function_space_collection + use mesh_mod, only: mesh_type + use multigrid_config_mod, only: multigrid_chain_nitems + use r_solver_field_mod, only: r_solver_field_type + + + implicit none + + ! Arguments + class(adj_solver_lookup_cache_type), intent(inout) :: self + type(mesh_type), pointer, intent(in) :: mesh + + ! Internal variables + type(function_space_type), pointer :: vector_space_w3_ptr + type(r_solver_field_type) :: vector_x + integer(kind=i_def) :: level + + nullify(vector_space_w3_ptr) + + ! ========================================================================= + ! Creating lookup_apply_hho + ! ========================================================================= + vector_space_w3_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, W3 & + ) + + if(l_multigrid) then + self%multigrid_levels=multigrid_chain_nitems + else + self%multigrid_levels=1 + end if + ! Extra level needed for coarse operator + allocate(self%lookup_apply_hho(self%multigrid_levels + 1)) + + if (l_multigrid) then + call multigrid_function_space_chain%set_current(vector_space_w3_ptr%get_id()) + end if + + do level = 1, self%multigrid_levels + 1 + call vector_x%initialise(vector_space_w3_ptr) + call invoke(setval_c(vector_x, 0.0_r_solver)) + call create_lookup_apply_helmholtz_op(self%lookup_apply_hho(level), & + vector_x) + if((l_multigrid) .and. (level < self%multigrid_levels)) then + vector_space_w3_ptr => multigrid_function_space_chain%get_next() + end if + end do + + self%is_initialised = .true._l_def + + end subroutine adj_solver_lookup_cache_init + + !============================================================================= + ! Getters + !============================================================================= + + !============================================================================= + !> @brief Return a pointer to the apply_hho lookup table. + !> @param [in] self Lookup table cache + !> @param [in] level Multigrid level to obtain lookup for + !> @return lookup_ptr The lookup table + function get_lookup_apply_hho(self, level) result(lookup_ptr) + + implicit none + + ! Arguments + class(adj_solver_lookup_cache_type), target, intent(in) :: self + integer(kind=i_def), intent(in) :: level + + ! Returns + type(adj_lookup_table_type), pointer :: lookup_ptr + + if (.not. self%is_initialised) call log_event("Cannot get lookup: cache is not initialised", LOG_LEVEL_ERROR) + if ((level < 1) .and. (level > self%multigrid_levels + 1)) then + write(log_scratch_space,*) "get_lookup_apply_hho: Requested level must be between 1 and ", & + self%multigrid_levels + 1, "but level = ", level + call log_event(log_scratch_space, LOG_LEVEL_ERROR) + end if + nullify(lookup_ptr) + lookup_ptr => self%lookup_apply_hho(level) + + end function get_lookup_apply_hho + + !============================================================================= + !> @brief Destructor. + !> @param [in,out] self Lookup table cache + subroutine adj_solver_lookup_cache_final(self) + + implicit none + + ! Arguments + class(adj_solver_lookup_cache_type), intent(inout) :: self + + ! Internal variables + integer(kind=i_def) :: level + + if (self%is_initialised) then + do level = 1, self%multigrid_levels + 1 + call self%lookup_apply_hho(level)%finalise() + end do + if (allocated(self%lookup_apply_hho)) deallocate(self%lookup_apply_hho) + end if + + end subroutine adj_solver_lookup_cache_final + +end module adj_solver_lookup_cache_mod diff --git a/science/adjoint/source/algorithm/lookup/transport/adj_trans_lookup_cache_mod.x90 b/science/adjoint/source/algorithm/lookup/transport/adj_trans_lookup_cache_mod.x90 new file mode 100644 index 000000000..292671ca9 --- /dev/null +++ b/science/adjoint/source/algorithm/lookup/transport/adj_trans_lookup_cache_mod.x90 @@ -0,0 +1,415 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +!> @brief Module containing the cached lookup table object. +module adj_trans_lookup_cache_mod + + use adj_lookup_table_mod, only: adj_lookup_table_type + use constants_mod, only: i_def, l_def + use fs_continuity_mod, only: W3, Wtheta, & + W2, W2H + use log_mod, only: log_event, & + log_scratch_space, & + LOG_LEVEL_ERROR + + implicit none + + !> @brief Adjoint lookup table cache type. + !> @details Cache containing the lookup tables needed for each stencil kernel, + !> for every combination of function spaces needed. + type, public :: adj_trans_lookup_cache_type + private + + !> Lookup table for adj_poly1d_reconstruction_kernel. + type(adj_lookup_table_type) :: lookup_poly1d + + !> Lookup table for adj_poly2d_reconstruction_kernel. + !> First index is on the W3 function space, second on Wtheta. + type(adj_lookup_table_type), allocatable, dimension(:) :: lookup_poly2d + + !> Lookup table for adj_poly_adv_update_kernel. + type(adj_lookup_table_type) :: lookup_poly_adv_upd + + !> Lookup table for adj_w3h_advective_update_kernel. + !> First index is on W2, second on W2H. + type(adj_lookup_table_type), allocatable, dimension(:) :: lookup_w3h_adv_upd + + !> Number of function spaces for lookup_poly2d. + integer(kind=i_def) :: n_fs_poly2d + + !> Number of function spaces for lookup_w3h_adv_upd. + integer(kind=i_def) :: n_fs_w3h_adv_upd + + !> Flag to state whether or not cache is initialised + logical(kind=l_def) :: is_initialised = .false._l_def + + contains + + procedure, public :: initialise => adj_trans_lookup_cache_init + procedure, public :: get_lookup_poly1d + procedure, public :: get_lookup_poly2d + procedure, public :: get_lookup_poly_adv_upd + procedure, public :: get_lookup_w3h_adv_upd + procedure, public :: finalise => adj_trans_lookup_cache_final + + end type adj_trans_lookup_cache_type + + contains + + !============================================================================= + !> @brief Initialise the lookup table cache. + !> @param [in,out] self Lookup table cache + !> @param [in] mesh Pointer to mesh + subroutine adj_trans_lookup_cache_init(self, mesh) + + use adj_lookup_table_generators_alg_mod, only: create_lookup_poly1d, & + create_lookup_poly2d, & + create_lookup_poly_adv_upd, & + create_lookup_w3h_adv_upd + use constants_mod, only: r_tran + use finite_element_config_mod, only: element_order_h, & + element_order_v + use function_space_mod, only: function_space_type + use function_space_collection_mod, only: function_space_collection + use mesh_mod, only: mesh_type + use operator_mod, only: operator_type + use r_tran_field_mod, only: r_tran_field_type + use sci_fem_constants_mod, only: get_inverse_mass_matrix_fe + use transport_config_mod, only: fv_horizontal_order + use transport_constants_mod, only: get_hori_wt_mol_coeffs + + + implicit none + + ! Arguments + class(adj_trans_lookup_cache_type), intent(inout) :: self + type(mesh_type), pointer, intent(in) :: mesh + + ! Internal variables + ! Shared + integer(kind=i_def) :: mesh_id + type(r_tran_field_type) :: advective + type(r_tran_field_type) :: wind + type(r_tran_field_type) :: reconstruction + integer(kind=i_def) :: stencil_extent + integer(kind=i_def) :: stencil_size + type(r_tran_field_type), pointer :: coeff + integer(kind=i_def) :: ndata + integer(kind=i_def) :: order + type(function_space_type), pointer :: vector_space_wtheta_ptr + type(function_space_type), pointer :: vector_space_w3_ptr + + ! lookup_poly1d + type(function_space_type), pointer :: vector_space_wt_md_ptr + + ! lookup_poly2d + integer(kind=i_def) :: fspace_enum + integer(kind=i_def) :: fspace_iterator + type(function_space_type), pointer :: vector_space_fs_md_ptr + type(function_space_type), pointer :: vector_space_fs_ptr + + ! lookup_poly_adv_upd + type(function_space_type), pointer :: vector_space_w2h_ptr + + ! lookup_w3h_adv_upd + type(r_tran_field_type) :: tracer + type(operator_type), pointer :: m3_inv + type(function_space_type), pointer :: vector_space_w3_md_ptr + type(function_space_type), pointer :: vector_space_w2_ptr + + nullify(coeff, & + m3_inv, & + vector_space_fs_ptr, & + vector_space_fs_md_ptr, & + vector_space_wtheta_ptr, & + vector_space_wt_md_ptr, & + vector_space_w2_ptr, & + vector_space_w2h_ptr, & + vector_space_w3_ptr, & + vector_space_w3_md_ptr) + + mesh_id = mesh%get_id() + + ! ========================================================================= + ! Creating lookup_poly1d + ! ========================================================================= + stencil_size = fv_horizontal_order + 1 + ndata = 4*stencil_size + coeff => get_hori_wt_mol_coeffs(mesh_id) + stencil_extent = fv_horizontal_order/2_i_def + order = fv_horizontal_order + vector_space_wt_md_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, wtheta, ndata=ndata & + ) + vector_space_wtheta_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, wtheta & + ) + + call reconstruction%initialise(vector_space=vector_space_wt_md_ptr, name='reconstruction') + call tracer%initialise(vector_space=vector_space_wtheta_ptr, name='tracer', halo_depth=2) + + call invoke(setval_c(reconstruction, 0.0_r_tran), & + setval_c(tracer, 0.0_r_tran)) + + call create_lookup_poly1d(self%lookup_poly1d, & + reconstruction, & + tracer, & + coeff, & + stencil_extent, & + order) + + ! ========================================================================= + ! Creating lookup_poly2d + ! ========================================================================= + self%n_fs_poly2d = 2_i_def + allocate(self%lookup_poly2d(self%n_fs_poly2d)) + if (mod(fv_horizontal_order, 2) == 0) then + stencil_size = 1 + 2*fv_horizontal_order + fv_horizontal_order**2 + else + stencil_size = max(1, 4*fv_horizontal_order + fv_horizontal_order**2) + end if + ndata = 4_i_def + + do fspace_iterator = 1_i_def, self%n_fs_poly2d + if (fspace_iterator == 1_i_def) then + fspace_enum = W3 + else + fspace_enum = Wtheta + end if + + vector_space_fs_md_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, fspace_enum, ndata=ndata, ndata_first=.false. & + ) + vector_space_fs_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, fspace_enum & + ) + + call reconstruction%initialise(vector_space=vector_space_fs_md_ptr, name='reconstruction') + call tracer%initialise(vector_space=vector_space_fs_ptr, name='tracer', halo_depth=2) + + call invoke(setval_c(reconstruction, 0.0_r_tran), & + setval_c(tracer, 0.0_r_tran)) + + call create_lookup_poly2d(self%lookup_poly2d(fspace_iterator), & + reconstruction, & + tracer, & + coeff, & + stencil_size, & + stencil_extent) + + + end do + + ! ========================================================================= + ! Creating lookup_poly_adv_upd + ! ========================================================================= + stencil_extent = 1_i_def + + vector_space_w2h_ptr => function_space_collection%get_fs(mesh, element_order_h, & + element_order_v, w2h) + vector_space_wt_md_ptr => function_space_collection%get_fs(mesh, element_order_h, & + element_order_v, wtheta, ndata) + + call advective%initialise(vector_space=vector_space_wtheta_ptr, name='advective') + call reconstruction%initialise(vector_space=vector_space_wt_md_ptr, name='reconstruction', halo_depth=stencil_extent) + call wind%initialise(vector_space=vector_space_w2h_ptr, name='wind', halo_depth=stencil_extent) + + call invoke(setval_c(advective, 0.0_r_tran), & + setval_c(reconstruction, 0.0_r_tran), & + setval_c(wind, 0.0_r_tran)) + call create_lookup_poly_adv_upd(self%lookup_poly_adv_upd, & + advective, & + reconstruction, & + wind, & + stencil_extent) + + ! ========================================================================= + ! Creating lookup_w3h_adv_upd + ! ========================================================================= + self%n_fs_w3h_adv_upd = 2_i_def + allocate(self%lookup_w3h_adv_upd(self%n_fs_w3h_adv_upd)) + m3_inv => get_inverse_mass_matrix_fe(W3, mesh_id) + ndata = 6_i_def + + do fspace_iterator = 1_i_def, self%n_fs_w3h_adv_upd + if (fspace_iterator == 1_i_def) then + fspace_enum = W2 + else + fspace_enum = W2H + end if + + vector_space_w3_md_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, W3, ndata, ndata_first=.false. & + ) + vector_space_w3_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, W3 & + ) + vector_space_fs_ptr => function_space_collection%get_fs( & + mesh, element_order_h, element_order_v, fspace_enum & + ) + + call advective%initialise(vector_space=vector_space_w3_ptr, name='advective') + call tracer%initialise(vector_space=vector_space_w3_md_ptr, name='tracer') + call wind%initialise(vector_space=vector_space_fs_ptr, name='wind') + + call invoke(setval_c(advective, 0.0_r_tran), & + setval_c(tracer, 0.0_r_tran), & + setval_c(wind, 0.0_r_tran)) + call create_lookup_w3h_adv_upd(self%lookup_w3h_adv_upd(fspace_iterator), & + advective, & + tracer, & + wind, & + m3_inv, & + stencil_extent) + end do + + self%is_initialised = .true._l_def + + end subroutine adj_trans_lookup_cache_init + + !============================================================================= + ! Getters + !============================================================================= + + !============================================================================= + !> @brief Return a pointer to the poly1d lookup table. + !> @param [in] self Lookup table cache + !> @return lookup_ptr The lookup table + function get_lookup_poly1d(self) result(lookup_ptr) + + implicit none + + ! Arguments + class(adj_trans_lookup_cache_type), target, intent(in) :: self + + ! Returns + type(adj_lookup_table_type), pointer :: lookup_ptr + + if (.not. self%is_initialised) call log_event("Cannot get lookup: cache is not initialised", LOG_LEVEL_ERROR) + nullify(lookup_ptr) + lookup_ptr => self%lookup_poly1d + + end function get_lookup_poly1d + + !============================================================================= + !> @brief Return a pointer to the poly2d lookup table for a given function space. + !> @param [in] self Lookup table cache + !> @param [in] fspace_enum Function space enumerator + !> @return lookup_ptr The lookup table + function get_lookup_poly2d(self, fspace_enum) result(lookup_ptr) + + implicit none + + ! Arguments + class(adj_trans_lookup_cache_type), target, intent(in) :: self + integer(kind=i_def), intent(in) :: fspace_enum + + ! Internal variables + integer(kind=i_def) :: fspace_index + + ! Returns + type(adj_lookup_table_type), pointer :: lookup_ptr + + if (.not. self%is_initialised) call log_event("Cannot get lookup: cache is not initialised", LOG_LEVEL_ERROR) + nullify(lookup_ptr) + fspace_index = 0_i_def + select case(fspace_enum) + case (W3) + fspace_index = 1_i_def + case (Wtheta) + fspace_index = 2_i_def + case default + write(log_scratch_space, *) "Invalid functionspace chosen for get_lookup_poly2d, must be W3 or Wtheta" + call log_event(log_scratch_space, LOG_LEVEL_ERROR) + end select + lookup_ptr => self%lookup_poly2d(fspace_index) + + end function get_lookup_poly2d + + !============================================================================= + !> @brief Return a pointer to the poly_adv_upd lookup table. + !> @param [in] self Lookup table cache + !> @return lookup_ptr The lookup table + function get_lookup_poly_adv_upd(self) result(lookup_ptr) + + implicit none + + ! Arguments + class(adj_trans_lookup_cache_type), target, intent(in) :: self + + ! Returns + type(adj_lookup_table_type), pointer :: lookup_ptr + + if (.not. self%is_initialised) call log_event("Cannot get lookup: cache is not initialised", LOG_LEVEL_ERROR) + nullify(lookup_ptr) + lookup_ptr => self%lookup_poly_adv_upd + + end function get_lookup_poly_adv_upd + + !============================================================================= + !> @brief Return a pointer to the w3h_adv_upd lookup table. + !> @param [in] self Lookup table cache + !> @param [in] fspace_enum Function space enumerator + !> @return lookup_ptr The lookup table + function get_lookup_w3h_adv_upd(self, fspace_enum) result(lookup_ptr) + + implicit none + + ! Arguments + class(adj_trans_lookup_cache_type), target, intent(in) :: self + integer(kind=i_def), intent(in) :: fspace_enum + + ! Internal variables + integer(kind=i_def) :: fspace_index + + ! Returns + type(adj_lookup_table_type), pointer :: lookup_ptr + + if (.not. self%is_initialised) call log_event("Cannot get lookup: cache is not initialised", LOG_LEVEL_ERROR) + nullify(lookup_ptr) + fspace_index = 0_i_def + select case(fspace_enum) + case (W2) + fspace_index = 1_i_def + case (W2H) + fspace_index = 2_i_def + case default + write(log_scratch_space, *) "Invalid functionspace chosen for get_lookup_w3h_adv_upd, must be W2 or W2H" + call log_event(log_scratch_space, LOG_LEVEL_ERROR) + end select + lookup_ptr => self%lookup_w3h_adv_upd(fspace_index) + + end function get_lookup_w3h_adv_upd + + !============================================================================= + !> @brief Destructor. + !> @param [in,out] self Lookup table cache + subroutine adj_trans_lookup_cache_final(self) + + implicit none + + ! Arguments + class(adj_trans_lookup_cache_type), intent(inout) :: self + + ! Internal variables + integer(kind=i_def) :: fspace_index + + if (self%is_initialised) then + call self%lookup_poly1d%finalise() + do fspace_index = 1_i_def, self%n_fs_poly2d + call self%lookup_poly2d(fspace_index)%finalise() + end do + call self%lookup_poly_adv_upd%finalise() + do fspace_index = 1_i_def, self%n_fs_w3h_adv_upd + call self%lookup_w3h_adv_upd(fspace_index)%finalise() + end do + if (allocated(self%lookup_poly2d)) deallocate(self%lookup_poly2d) + if (allocated(self%lookup_w3h_adv_upd)) deallocate(self%lookup_w3h_adv_upd) + end if + + end subroutine adj_trans_lookup_cache_final + +end module adj_trans_lookup_cache_mod diff --git a/science/adjoint/source/algorithm/solver/adj_mixed_operator_alg_mod.x90 b/science/adjoint/source/algorithm/solver/adj_mixed_operator_alg_mod.x90 index d4b2998e2..f99278816 100644 --- a/science/adjoint/source/algorithm/solver/adj_mixed_operator_alg_mod.x90 +++ b/science/adjoint/source/algorithm/solver/adj_mixed_operator_alg_mod.x90 @@ -30,7 +30,6 @@ module adj_mixed_operator_alg_mod use function_space_collection_mod, only: function_space_collection use function_space_mod, only: function_space_type use integer_field_mod, only: integer_field_type - use io_config_mod, only: subroutine_timers use limited_area_constants_mod, only: get_mask_r_solver use log_mod, only: log_event, & LOG_LEVEL_ERROR @@ -54,7 +53,9 @@ module adj_mixed_operator_alg_mod get_eliminated_q32 use solver_constants_mod, only: get_w2_mass_matrix_r_solver, & get_normalisation_r_solver - use timer_mod, only: timer + use timing_mod, only: start_timing, & + stop_timing, & + tik, LPROF use vector_mod, only: abstract_vector_type implicit none @@ -103,8 +104,9 @@ contains type(r_solver_field_vector_type) :: x_in integer(kind=i_def) :: state_size + integer(tik) :: id - if (subroutine_timers) call timer('adj_mixed_operator') + if ( LPROF ) call start_timing( id, 'adj_mixed_solver.operator' ) ! Extract mesh ID select type (y) @@ -257,7 +259,7 @@ contains call log_event( "mixed_operator_alg_mod: incorrect vector_type argument x", LOG_LEVEL_ERROR ) end select - if (subroutine_timers) call timer('adj_mixed_operator') + if ( LPROF ) call stop_timing( id, 'adj_mixed_solver.operator' ) end subroutine apply_adj_mixed_operator diff --git a/science/adjoint/source/algorithm/solver/adj_mixed_schur_preconditioner_alg_mod.x90 b/science/adjoint/source/algorithm/solver/adj_mixed_schur_preconditioner_alg_mod.x90 index fa8308975..df98ce9eb 100644 --- a/science/adjoint/source/algorithm/solver/adj_mixed_schur_preconditioner_alg_mod.x90 +++ b/science/adjoint/source/algorithm/solver/adj_mixed_schur_preconditioner_alg_mod.x90 @@ -20,8 +20,8 @@ module adj_mixed_schur_preconditioner_alg_mod isol_uv, isol_w use function_space_mod, only: function_space_type use function_space_collection_mod, only: function_space_collection - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use mixed_solver_config_mod, only: split_w use log_mod, only: log_event, & LOG_LEVEL_ERROR, & @@ -132,8 +132,10 @@ contains type(r_solver_field_type) :: exner_inc type(r_solver_field_type) :: pressure_b_field + integer(tik) :: id_precon, id_solve - if (subroutine_timers) call timer('adj_mixed_schur_preconditioner_alg') + if ( LPROF ) call start_timing( id_precon, & + 'adj_mixed_solver.schur_precon' ) select type(x) type is(r_solver_field_vector_type) @@ -169,9 +171,9 @@ contains ! Solve pressure system call log_event( 'Schur preconditioner pressure solve:', LOG_LEVEL_DEBUG ) - if (subroutine_timers) call timer('adj mixed_schur solve') + if ( LPROF ) call start_timing( id_solve, 'adj_schur_precon.pressure_solver' ) call self%adj_pressure_solver%apply( self%pressure_x, self%pressure_b ) - if (subroutine_timers) call timer('adj mixed_schur solve') + if ( LPROF ) call stop_timing( id_solve, 'adj_schur_precon.pressure_solver' ) ! STEP 1: Build RHS for Helmholtz system @@ -193,7 +195,8 @@ contains call log_event( "mixed_schur_preconditioner_mod: incorrect vector_type argument x", LOG_LEVEL_ERROR ) end select - if (subroutine_timers) call timer('adj_mixed_schur_preconditioner_alg') + if ( LPROF ) call stop_timing( id_precon, & + 'adj_mixed_solver.schur_precon' ) end subroutine apply_adj_mixed_schur_preconditioner @@ -216,8 +219,9 @@ contains type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns + integer(tik) :: id - if (subroutine_timers) call timer('adj mixed_schur rhs') + if ( LPROF ) call start_timing( id, 'adj_schur_precon.rhs' ) ! Options coded: ! element_order_h= 0 @@ -300,7 +304,7 @@ contains call log_event( "adj_build_pressure_rhs: .not. split_w not coded", LOG_LEVEL_ERROR ) end if - if (subroutine_timers) call timer('adj mixed_schur rhs') + if ( LPROF ) call stop_timing( id, 'adj_schur_precon.rhs' ) end subroutine adj_build_pressure_rhs @@ -322,8 +326,9 @@ contains type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns + integer(tik) :: id - if (subroutine_timers) call timer('adj Schur back substitute') + if ( LPROF ) call start_timing( id, 'adj_schur_precon.back_sub' ) exner_inc => self%pressure_x%get_field_from_position(1) @@ -370,7 +375,7 @@ contains Hb_lumped_inv ), & setval_c(u_inc, 0.0_r_solver) ) - if (subroutine_timers) call timer('adj Schur back substitute') + if ( LPROF ) call stop_timing( id, 'adj_schur_precon.back_sub' ) end subroutine adj_back_substitute diff --git a/science/adjoint/source/algorithm/solver/adj_pressure_operator_alg_mod.x90 b/science/adjoint/source/algorithm/solver/adj_pressure_operator_alg_mod.x90 index bc6116949..6fae39423 100644 --- a/science/adjoint/source/algorithm/solver/adj_pressure_operator_alg_mod.x90 +++ b/science/adjoint/source/algorithm/solver/adj_pressure_operator_alg_mod.x90 @@ -19,13 +19,14 @@ module adj_pressure_operator_alg_mod use base_mesh_config_mod, only: topology, topology_non_periodic use invoke_adj_a_h_o_lookup_kernel_mod, only: invoke_adj_a_h_o_lookup_kernel - use adj_lookup_table_generators_alg_mod, only: create_lookup_apply_helmholtz_op + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type use adj_lookup_table_mod, only: adj_lookup_table_type use integer_field_mod, only: integer_field_type use finite_element_config_mod, only: element_order_h, element_order_v - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, & + stop_timing, & + tik, LPROF use si_operators_alg_mod, only: get_helmholtz_operator implicit none @@ -34,7 +35,8 @@ module adj_pressure_operator_alg_mod type, public, extends(abstract_hierarchical_linear_operator_type) :: adj_pressure_operator_type private - integer(kind=i_def) :: level + integer(kind=i_def) :: level + type(adj_solver_lookup_cache_type), pointer :: adj_lookup_table_cache_ptr contains procedure, public :: apply => apply_adj_pressure_operator procedure, private :: apply_adj_pressure_operator @@ -52,18 +54,21 @@ module adj_pressure_operator_alg_mod contains !> @brief Construct new instance of type. - !> @param[in] level The mesh level the space is on - function adj_pressure_operator_constructor(level) result(self) + !> @param[in] level The mesh level the space is on + !> @param[in] adj_lookup_table_cache The lookup table cache + function adj_pressure_operator_constructor(level, adj_lookup_table_cache) result(self) implicit none - integer(kind=i_def), intent(in) :: level - type(adj_pressure_operator_type) :: self + integer(kind=i_def), intent(in) :: level + type(adj_solver_lookup_cache_type), target, intent(in) :: adj_lookup_table_cache + type(adj_pressure_operator_type) :: self call log_event( 'Constructing adjoint pressure_operator...', LOG_LEVEL_DEBUG ) ! Temporaries required in operator application self%level = level + self%adj_lookup_table_cache_ptr => adj_lookup_table_cache call log_event( 'done', LOG_LEVEL_DEBUG ) @@ -81,6 +86,7 @@ contains ! Deep copy of the contents of the adj_pressure_operator_type dest%level = source%level + dest%adj_lookup_table_cache_ptr => source%adj_lookup_table_cache_ptr end subroutine adj_pressure_operator_assign @@ -104,14 +110,16 @@ contains logical(kind=l_def) :: lam_mesh ! Lookup table - type(adj_lookup_table_type) :: lookup - type(integer_field_type), pointer :: lookup_field - type(integer_field_type), pointer :: set_counts_field - integer(kind=i_def) :: nindices + type(adj_lookup_table_type), pointer :: lookup + type(integer_field_type), pointer :: lookup_field + type(integer_field_type), pointer :: set_counts_field + integer(kind=i_def) :: nindices + + integer(tik) :: id nullify( Helmholtz_operator, x_vec, y_vec, lookup_field, set_counts_field ) - if (subroutine_timers) call timer('adj helmholtz lhs') + if ( LPROF ) call start_timing( id, 'adj_pressure_solver.helmholtz_lhs' ) select type (x) type is (r_solver_field_vector_type) @@ -137,8 +145,7 @@ contains setval_c( y_vec, 0.0_r_solver ) ) ! Run adj_apply_helmholtz_operator kernel. - ! Generate adjoint lookup table for stencil operation. Dry run of the TL code, horizontal only. - call create_lookup_apply_helmholtz_op( lookup, x_vec ) + lookup => self%adj_lookup_table_cache_ptr%get_lookup_apply_hho(self%level) lookup_field => lookup%get_lookup_field() set_counts_field => lookup%get_set_count_field() nindices = lookup%get_nindices() @@ -155,8 +162,6 @@ contains call log_event( "apply_adj_pressure_operator: element_orders /= 0 not coded", LOG_LEVEL_ERROR ) end if - if (subroutine_timers) call timer('adj helmholtz lhs') - class default call log_event( "adj_pressure_operator_alg_mod: incorrect vector_type argument y", LOG_LEVEL_ERROR ) end select @@ -164,6 +169,7 @@ contains class default call log_event( "adj_pressure_operator_alg_mod: incorrect vector_type argument x", LOG_LEVEL_ERROR ) end select + if ( LPROF ) call stop_timing( id, 'adj_pressure_solver.helmholtz_lhs' ) call log_event( "apply_adj_pressure_operator: end", LOG_LEVEL_DEBUG ) @@ -180,7 +186,7 @@ contains class(abstract_hierarchical_linear_operator_type), allocatable, intent(inout) :: coarse_operator allocate( coarse_operator, & - source = adj_pressure_operator_type(self%level + 1) ) + source = adj_pressure_operator_type(self%level + 1, self%adj_lookup_table_cache_ptr) ) end subroutine coarsen_adj_pressure_operator diff --git a/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 b/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 index c5da78977..3a1f0ee48 100644 --- a/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 +++ b/science/adjoint/source/algorithm/solver/adj_semi_implicit_solver_alg_mod.x90 @@ -23,16 +23,19 @@ module adj_semi_implicit_solver_alg_mod use adj_mixed_operator_alg_mod, only: adj_mixed_operator_type use adj_mixed_schur_preconditioner_alg_mod, only: adj_mixed_schur_preconditioner_type use adj_pressure_precon_alg_mod, only: adj_pressure_preconditioner_type + use multigrid_preconditioner_alg_mod, only: multigrid_preconditioner_type use pressure_operator_alg_mod, only: pressure_operator_type + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type use adj_pressure_operator_alg_mod, only: adj_pressure_operator_type use sci_null_preconditioner_alg_mod, only: null_preconditioner_type use sci_preconditioner_mod, only: abstract_preconditioner_type use sci_iterative_solver_mod, only: abstract_iterative_solver_type, & + precondition_only_type, & bicgstab_type, block_gcr_type use split_w2_field_kernel_mod, only: split_w2_field_kernel_type use combine_w2_field_kernel_mod, only: combine_w2_field_kernel_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use finite_element_config_mod, only: element_order_h, element_order_v use copy_field_alg_mod, only: copy_field use function_space_collection_mod, only: function_space_collection @@ -52,6 +55,7 @@ module adj_semi_implicit_solver_alg_mod si_pressure_a_tol, & helmholtz_method => method, & method_bicgstab, & + method_prec_only, & si_pressure_monitor_convergence => monitor_convergence, & si_pressure_fail_on_non_converged => fail_on_non_converged @@ -85,21 +89,36 @@ contains !> @brief Create adjoint operator and preconditioner for (Helmholtz) pressure problem !> @details Called by init method of this module, but also by !! adjt_mixed_schur_preconditioner_alg_mod and adjt_mixed_solver_alg_mod - !> @param[out] pressure_operator_out Output (Helmholtz) pressure operator - !> @param[out] pressure_preconditioner_out Output (Helmholtz) pressure preconditioner - subroutine create_adj_pressure_preconditioner( adj_pressure_operator_out, adj_pressure_preconditioner_out ) + !> @param[in] state Prognostic state for the adjoint pressure preconditioner + !> @param[in] adj_lookup_table_cache The lookup table cache + !> @param[out] adj_pressure_operator_out Output adjoint (Helmholtz) pressure operator + !> @param[out] adj_pressure_preconditioner_out Output adjoint (Helmholtz) pressure preconditioner + subroutine create_adj_pressure_preconditioner( state, adj_lookup_table_cache, & + adj_pressure_operator_out, adj_pressure_preconditioner_out ) use helmholtz_solver_config_mod, only: helmholtz_preconditioner => preconditioner, & preconditioner_none, & - preconditioner_tridiagonal + preconditioner_tridiagonal, & + preconditioner_multigrid implicit none + ! Prognostic fields + type(field_type), dimension(bundle_size), intent(in) :: state + type(adj_solver_lookup_cache_type), intent(in) :: adj_lookup_table_cache + ! Output adjoint operator and preconditioner for (Helmholtz) pressure problem type(adj_pressure_operator_type), intent(out) :: adj_pressure_operator_out class(abstract_preconditioner_type), allocatable, intent(out) :: adj_pressure_preconditioner_out - adj_pressure_operator_out = adj_pressure_operator_type(level=1_i_def) + ! Vertical pressure preconditioner + type(adj_pressure_preconditioner_type) :: adj_helmholtz_preconditioner + + integer(kind=i_def) :: level + + level = 1_i_def + + adj_pressure_operator_out = adj_pressure_operator_type(level, adj_lookup_table_cache) call log_event( "adj_semi_implicit_solver_type%create_adj_pressure_preconditioner: starting", LOG_LEVEL_INFO ) @@ -111,6 +130,12 @@ contains case(PRECONDITIONER_TRIDIAGONAL) allocate( adj_pressure_preconditioner_out, & source = adj_pressure_preconditioner_type(level=1_i_def) ) + case(PRECONDITIONER_MULTIGRID) + adj_helmholtz_preconditioner = adj_pressure_preconditioner_type(level=1_i_def) + allocate( adj_pressure_preconditioner_out, & + source = multigrid_preconditioner_type( state(igh_p)%get_function_space(), & + adj_pressure_operator_out, & + adj_helmholtz_preconditioner ) ) case default call log_event( "Invalid pressure preconditioner specified for adjoint", LOG_LEVEL_ERROR ) end select @@ -148,6 +173,11 @@ contains si_pressure_maximum_iterations, & si_pressure_monitor_convergence, & si_pressure_fail_on_non_converged ) ) + case(METHOD_PREC_ONLY) + allocate( adj_pressure_solver_out, & + source = precondition_only_type( adj_pressure_operator_in, & + adj_pressure_preconditioner_in, & + si_pressure_monitor_convergence ) ) case default call log_event( "Invalid pressure solver specified for adjoint", LOG_LEVEL_ERROR ) end select @@ -234,16 +264,19 @@ contains !> @brief Initialisation procedure for the adjoint semi-implicit solver !> @param[in] state Prognostic state for the solver - subroutine initialise( self, state ) + subroutine initialise( self, state, adj_lookup_table_cache ) implicit none ! Arguments - class(adj_semi_implicit_solver_type), intent(inout) :: self - type(field_type), dimension(bundle_size), intent(in) :: state - - self%adj_pressure_operator = adj_pressure_operator_type(level=1_i_def) - call create_adj_pressure_preconditioner( self%adj_pressure_operator, self%adj_pressure_preconditioner ) + class(adj_semi_implicit_solver_type), intent(inout) :: self + type(field_type), dimension(bundle_size), intent(in) :: state + type(adj_solver_lookup_cache_type), intent(in) :: adj_lookup_table_cache + + call create_adj_pressure_preconditioner( state, & + adj_lookup_table_cache, & + self%adj_pressure_operator, & + self%adj_pressure_preconditioner ) call create_adj_pressure_solver( self%adj_pressure_operator, self%adj_pressure_preconditioner, self%adj_pressure_solver ) call create_adj_mixed_preconditioner( state, self%adj_pressure_solver, self%adj_mixed_preconditioner ) call create_adj_mixed_solver( self%adj_mixed_preconditioner, self%adj_mixed_operator, self%adj_mixed_solver ) @@ -318,8 +351,9 @@ contains type(integer_field_type), pointer :: face_selector_ew, face_selector_ns type(mesh_type), pointer :: mesh integer(kind=i_def) :: p_h, p_v + integer(tik) :: id_si, id_mix - if (subroutine_timers) call timer('adj_semi_implicit_solver_type%step') + if ( LPROF ) call start_timing( id_si, 'adjoint.solver') ! Input fields are r_def fields so preliminary work uses field_types @@ -434,10 +468,10 @@ contains call vector_rhs%import_field( inc_exner_rsol, isol_p ) ! Solve the semi-implicit operator - if (subroutine_timers) call timer('adj_mixed_solver') + if ( LPROF ) call start_timing( id_mix, 'adj_solver.mixed_solver' ) call vector_inc%set_scalar(0.0_r_def) call self%adj_mixed_solver%apply( vector_inc, vector_rhs ) - if (subroutine_timers) call timer('adj_mixed_solver') + if ( LPROF ) call stop_timing( id_mix, 'adj_solver.mixed_solver' ) call deconstruct_solver_state( vector_inc, rhs_rsol ) ! vector_inc(uv,w,p) IN, rhs_rsol(u,p) OUT, rhs_rsol(d,t) unaffected @@ -489,7 +523,7 @@ contains call invoke(inc_X_times_Y( rhs(igh_u), u_normalisation )) - if (subroutine_timers) call timer( 'adj_semi_implicit_solver_type%step' ) + if ( LPROF ) call stop_timing( id_si, 'adjoint.solver') end subroutine step diff --git a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 index 04c466748..679e30c38 100644 --- a/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 +++ b/science/adjoint/source/algorithm/timestepping/atl_si_timestep_alg_mod.x90 @@ -17,7 +17,6 @@ module atl_si_timestep_alg_mod use formulation_config_mod, only: dlayer_on, exner_from_eos, si_momentum_equation, & moisture_formulation, moisture_formulation_dry, & use_physics, use_wavedynamics - use io_config_mod, only: subroutine_timers use mixed_solver_config_mod, only: guess_np1, reference_reset_time use timestepping_config_mod, only: alpha, spinup_alpha, & outer_iterations, inner_iterations @@ -25,6 +24,7 @@ module atl_si_timestep_alg_mod l_stabilise_bl, & n_bl_levels_to_stabilise, & max_bl_stabilisation + use linear_physics_config_mod, only: l_boundary_layer use derived_config_mod, only: bundle_size use boundaries_config_mod, only: limited_area use sci_fem_constants_mod, only: get_mass_matrix_fe, get_qr_fe @@ -45,6 +45,8 @@ module atl_si_timestep_alg_mod use rhs_alg_mod, only: rhs_alg use atl_rhs_alg_mod, only: atl_rhs_alg use gungho_transport_control_alg_mod, only: gungho_transport_control_alg + use adj_solver_lookup_cache_mod, only: adj_solver_lookup_cache_type + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use atl_transport_control_alg_mod, only: atl_transport_control_alg use si_operators_alg_mod, only: compute_si_operators use semi_implicit_solver_alg_mod, only: semi_implicit_solver_alg_step @@ -52,12 +54,14 @@ module atl_si_timestep_alg_mod use derive_exner_from_eos_alg_mod, only: derive_exner_from_eos use atl_derive_exner_from_eos_alg_mod, only: atl_derive_exner_from_eos use update_prognostic_scalars_alg_mod, only: update_prognostic_scalars_alg + use atl_physics_alg_mod, only: atl_physics_alg use mr_indices_mod, only: nummr use moist_dyn_mod, only: num_moist_factors, gas_law use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p use mixing_config_mod, only: smagorinsky use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_enumerated_types_mod, only: direction_3d, direction_h, direction_v implicit none @@ -75,6 +79,7 @@ module atl_si_timestep_alg_mod type(field_type), allocatable :: state2(:) type(field_type), allocatable :: state_copy(:) type(field_type), allocatable :: state_n(:) + type(field_type), allocatable :: state_star(:) type(field_type), allocatable :: state_after_slow(:) type(field_type), allocatable :: advected_state(:) type(field_type), allocatable :: mr_n(:) @@ -86,6 +91,7 @@ module atl_si_timestep_alg_mod type(field_type), allocatable :: state_test(:) type(field_type), allocatable :: rhs_np1_test(:) type(field_type), allocatable :: rhs_np1_in(:) + type(field_type), allocatable :: rhs_phys(:) ! Linearisation state type(field_type), allocatable :: ls_state(:) @@ -113,6 +119,10 @@ module atl_si_timestep_alg_mod ! Moisture flag logical(l_def) :: use_moisture + ! Adjoint lookup tables + type(adj_solver_lookup_cache_type) :: adj_solver_lookup_cache + type(adj_trans_lookup_cache_type) :: adj_trans_lookup_cache + contains procedure, public :: initialise @@ -173,6 +183,7 @@ contains allocate(self%state_copy(bundle_size)) allocate(self%state_n(bundle_size)) allocate(self%state_after_slow(bundle_size)) + allocate(self%state_star(bundle_size)) allocate(self%advected_state(bundle_size)) allocate(self%rhs_n(bundle_size)) allocate(self%rhs_np1(bundle_size)) @@ -183,6 +194,7 @@ contains allocate(self%state_test(bundle_size)) allocate(self%rhs_np1_test(bundle_size)) allocate(self%rhs_np1_in(bundle_size)) + allocate(self%rhs_phys(bundle_size)) allocate(self%ls_state(bundle_size)) allocate(self%ls_state_n(bundle_size)) @@ -225,6 +237,7 @@ contains call clone_bundle( self%state, self%state_test, bundle_size ) call clone_bundle( self%state, self%rhs_np1_test, bundle_size ) call clone_bundle( self%state, self%rhs_np1_in, bundle_size ) + call clone_bundle( self%state, self%rhs_phys, bundle_size ) call clone_bundle( self%state, self%ls_state, bundle_size ) call clone_bundle( self%state, self%ls_state_n, bundle_size ) @@ -270,7 +283,10 @@ contains call set_bundle_scalar( 0.0_r_def, self%ls_mr_after_slow, nummr ) end if - call self%adj_semi_implicit_solver%initialise(self%state) + call self%adj_solver_lookup_cache%initialise(u%get_mesh()) + call self%adj_trans_lookup_cache%initialise(u%get_mesh()) + + call self%adj_semi_implicit_solver%initialise(self%state, self%adj_solver_lookup_cache) call log_event( "atl_si_timestep_type%init: initialised timestepping algorithm", LOG_LEVEL_INFO ) @@ -321,8 +337,9 @@ contains type(field_type) :: advected_u type(mesh_type), pointer :: mesh character(len=str_def) :: prime_mesh_name + integer(tik) :: id - if (subroutine_timers) call timer('atl_si_timestep_type::step') + if ( LPROF ) call start_timing( id, 'atl_semi_implicit_timestep' ) cast_dt = real( modeldb%clock%get_seconds_per_step(), r_def ) @@ -554,6 +571,7 @@ contains call set_bundle_scalar( 0.0_r_def, self%state_initial, bundle_size ) call set_bundle_scalar( 0.0_r_def, self%rhs_n, bundle_size ) call set_bundle_scalar( 0.0_r_def, self%rhs_np1, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%rhs_phys, bundle_size ) call set_bundle_scalar( 0.0_r_def, self%mr_after_slow, nummr ) call set_bundle_scalar( 0.0_r_def, self%mr_n, nummr ) @@ -643,32 +661,73 @@ contains setval_c( self%rhs_np1(igh_t), 0.0_r_def ) ) end if + if (l_boundary_layer) call add_bundle(self%rhs_phys,self%rhs_np1,self%rhs_phys, bundle_size) call add_bundle( self%rhs_adv, self%rhs_np1, self%rhs_adv, bundle_size ) call add_bundle( self%rhs_n, self%rhs_np1, self%rhs_n, bundle_size ) call bundle_ax( -1.0_r_def, self%rhs_np1, self%rhs_np1, bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state1,bundle_size ) - call set_bundle_scalar( 0.0_r_def,self%state2,bundle_size ) + if (inner > 1) then + + if (use_wavedynamics) then + + call set_bundle_scalar( 0.0_r_def, self%state1, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state2, bundle_size ) - call atl_rhs_alg( self%rhs_np1, & - -varalpha*cast_dt, & - self%state1, & - self%state2, & - moist_dyn, & - self%ls_state_itns(:,ls_outer,ls_inner), & - self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & - .true., & - dlayer_on, & - modeldb%clock ) + call atl_rhs_alg( self%rhs_np1, & + -varalpha*cast_dt, & + self%state1, & + self%state2, & + moist_dyn, & + self%ls_state_itns(:,ls_outer,ls_inner), & + self%ls_moist_dyn_itns(:,ls_outer,ls_inner), & + .true., & + dlayer_on, & + modeldb%clock ) - call add_bundle( self%state,self%state2 ,self%state, bundle_size ) - call add_bundle( self%state,self%state1 ,self%state, bundle_size ) + call add_bundle( self%state, self%state2, self%state, bundle_size ) + call add_bundle( self%state, self%state1, self%state, bundle_size ) + + end if + + end if end do inner_dynamics_loop !------------------------------------------------------------------------- ! End of inner (nonlinear, Coriolis) loop !------------------------------------------------------------------------- + if (l_boundary_layer) then + ! Linear boundary layer scheme is currently the only linear physics scheme + call atl_physics_alg( modeldb, & + u, & + self%state_star, & + self%rhs_phys, & + self%rhs_np1, & + self%rhs_n, & + self%state, & + self%rhs_adv, & + self%ls_state_itns(:,ls_outer,1), & + mesh, & + cast_dt ) + end if ! l_boundary_layer + + call set_bundle_scalar( 0.0_r_def, self%state1, bundle_size ) + call set_bundle_scalar( 0.0_r_def, self%state2, bundle_size ) + + call atl_rhs_alg( self%rhs_np1, & + -varalpha*cast_dt, & + self%state1, & + self%state2, & + moist_dyn, & + self%ls_state_itns(:,ls_outer,1), & + self%ls_moist_dyn_itns(:,ls_outer,1), & + .true., & + dlayer_on, & + modeldb%clock ) + + call add_bundle( self%state, self%state2, self%state, bundle_size ) + call add_bundle( self%state, self%state1, self%state, bundle_size ) + call invoke( setval_c( self%theta_fv_inc, 0.0_r_def ), & adj_dg_inc_matrix_vector_kernel_type( self%rhs_adv(igh_t), & self%theta_fv_inc, mm_wt ), & @@ -685,7 +744,8 @@ contains self%ls_state_n(igh_u), & self%ls_mr_after_slow, & modeldb%clock, & - outer ) ! advected_state finished with + outer, & + self%adj_trans_lookup_cache ) ! advected_state finished with end do outer_dynamics_loop !--------------------------------------------------------------------------- @@ -737,7 +797,7 @@ contains setval_X( rho, self%state(igh_d) ), & setval_X( exner, self%state(igh_p) ) ) - if (subroutine_timers) call timer('atl_si_timestep_type::step') + if ( LPROF ) call stop_timing( id, 'atl_semi_implicit_timestep' ) end subroutine step @@ -758,6 +818,7 @@ contains if (allocated(self%state_n)) deallocate(self%state_n) if (allocated(self%state_initial)) deallocate(self%state_initial) if (allocated(self%state_after_slow)) deallocate(self%state_after_slow) + if (allocated(self%state_star)) deallocate(self%state_star) if (allocated(self%advected_state)) deallocate(self%advected_state) if (allocated(self%rhs_n)) deallocate(self%rhs_n) if (allocated(self%rhs_np1)) deallocate(self%rhs_np1) @@ -768,6 +829,7 @@ contains if (allocated(self%state_test)) deallocate(self%state_test) if (allocated(self%rhs_np1_test)) deallocate(self%rhs_np1_test) if (allocated(self%rhs_np1_in)) deallocate(self%rhs_np1_in) + if (allocated(self%rhs_phys)) deallocate(self%rhs_phys) if (allocated(self%ls_state)) deallocate(self%ls_state) if (allocated(self%ls_state_itns)) deallocate(self%ls_state_itns) @@ -784,6 +846,9 @@ contains if (allocated(self%ls_mr_itns)) deallocate(self%ls_mr_itns) if (allocated(self%ls_moist_dyn_itns)) deallocate(self%ls_moist_dyn_itns) + call self%adj_solver_lookup_cache%finalise() + call self%adj_trans_lookup_cache%finalise() + return end subroutine finalise diff --git a/science/adjoint/source/algorithm/transport/common/adj_end_transport_step_alg_mod.x90 b/science/adjoint/source/algorithm/transport/common/adj_end_transport_step_alg_mod.x90 index eb4c4e7ba..c12a86c82 100644 --- a/science/adjoint/source/algorithm/transport/common/adj_end_transport_step_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/common/adj_end_transport_step_alg_mod.x90 @@ -15,11 +15,11 @@ module adj_end_transport_step_alg_mod use sci_geometric_constants_mod, only: get_face_selector_ew, & get_face_selector_ns use integer_field_mod, only: integer_field_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_config_mod, only: dry_field_name use transport_enumerated_types_mod, only: direction_3d, & direction_h, & @@ -76,8 +76,9 @@ contains type(r_tran_field_type) :: combined_flux logical(kind=l_def) :: is_flux_3d logical(kind=l_def) :: is_flux_split + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.adj_build_up_flux') + if ( LPROF ) call start_timing( id, 'transport.adj_build_up_flux' ) ! Don't know which function space the fluxes are in -- add up each mesh => sum_flux%get_mesh() @@ -97,6 +98,14 @@ contains hori_flux => transport_counter%get_flux(2) call sum_vert_flux%initialise(w2v_fs) + if (.not. hori_flux%is_initialised() ) then + call hori_flux%initialise(w2h_fs) + call invoke( setval_c( hori_flux, 0.0_r_tran ) ) + end if + if (.not. old_flux%is_initialised() ) then + call old_flux%initialise(w2v_fs) + call invoke( setval_c( old_flux, 0.0_r_tran ) ) + end if call invoke( setval_c( sum_vert_flux, 0.0_r_tran ), & adj_combine_w2_field_kernel_type( sum_flux, hori_flux, & sum_vert_flux, & @@ -104,6 +113,7 @@ contains face_selector_ns ), & inc_X_plus_Y( old_flux, sum_vert_flux ), & inc_X_plus_Y( flux_last_step, sum_vert_flux ), & + setval_c( sum_flux, 0.0_r_tran ), & setval_c( sum_vert_flux, 0.0_r_tran ) ) ! General case for any splitting @@ -173,7 +183,7 @@ contains end if - if ( subroutine_timers ) call timer('transport.adj_build_up_flux') + if ( LPROF ) call stop_timing( id, 'transport.adj_build_up_flux' ) end subroutine adj_build_up_flux diff --git a/science/adjoint/source/algorithm/transport/common/adj_flux_precomputations_mod.x90 b/science/adjoint/source/algorithm/transport/common/adj_flux_precomputations_mod.x90 index f5c0dcb86..a742942de 100644 --- a/science/adjoint/source/algorithm/transport/common/adj_flux_precomputations_mod.x90 +++ b/science/adjoint/source/algorithm/transport/common/adj_flux_precomputations_mod.x90 @@ -141,7 +141,7 @@ module adj_flux_precomputations_mod class(flux_precomputations_type), intent(inout) :: flux_pc integer(kind=i_def), intent(in) :: step - type(r_tran_field_type), intent(in) :: ref_flux + type(r_tran_field_type), intent(inout) :: ref_flux ! Local variables integer(kind=i_def) :: splitting diff --git a/science/adjoint/source/algorithm/transport/common/atl_end_transport_step_alg_mod.x90 b/science/adjoint/source/algorithm/transport/common/atl_end_transport_step_alg_mod.x90 index 6f0cf3a45..7f135041b 100644 --- a/science/adjoint/source/algorithm/transport/common/atl_end_transport_step_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/common/atl_end_transport_step_alg_mod.x90 @@ -17,7 +17,6 @@ module atl_end_transport_step_alg_mod use fs_continuity_mod, only: W2, W2H, W2V use function_space_mod, only: function_space_type use function_space_collection_mod, only: function_space_collection - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use mesh_collection_mod, only: mesh_collection @@ -27,7 +26,6 @@ module atl_end_transport_step_alg_mod use r_tran_field_mod, only: r_tran_field_type use r_tran_operator_mod, only: r_tran_operator_type use split_transport_utils_mod, only: get_num_split_steps - use timer_mod, only: timer use transport_config_mod, only: cheap_update, & dry_field_name use transport_constants_mod, only: get_directional_im3_div_r_tran @@ -38,7 +36,6 @@ module atl_end_transport_step_alg_mod use transport_metadata_mod, only: transport_metadata_type use adj_flux_precomputations_mod, only: adj_initialise_step - implicit none private @@ -223,14 +220,18 @@ contains if (.not. final_split_step) then flux_ptr => transport_counter%get_flux( step ) - call invoke( inc_X_plus_Y( flux, flux_ptr ), & - setval_c( flux_ptr, 0.0_r_tran ) ) + call invoke( inc_X_plus_Y( flux, flux_ptr ) ) end if ! Combine fluxes from each part of the calculation call invoke( inc_X_plus_Y( flux_pert_wind, flux ), & inc_X_plus_Y( flux_ls_wind, flux ) ) + if (.not. final_split_step) then + flux_ptr => transport_counter%get_flux( step ) + call invoke( setval_c( flux_ptr, 0.0_r_tran ) ) + end if + end subroutine atl_end_conservative_step_alg end module atl_end_transport_step_alg_mod diff --git a/science/adjoint/source/algorithm/transport/control/atl_moist_mr_transport_alg_mod.x90 b/science/adjoint/source/algorithm/transport/control/atl_moist_mr_transport_alg_mod.x90 index 8c8c8824a..464147193 100644 --- a/science/adjoint/source/algorithm/transport/control/atl_moist_mr_transport_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/control/atl_moist_mr_transport_alg_mod.x90 @@ -9,12 +9,13 @@ module atl_moist_mr_transport_alg_mod use constants_mod, only: i_def, r_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR use mr_indices_mod, only: nummr - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use tl_transport_controller_mod, only: tl_transport_controller_type + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use transport_enumerated_types_mod, only: equation_form_advective, & equation_form_conservative use atl_transport_field_mod, only: atl_transport_field @@ -30,34 +31,36 @@ contains !============================================================================= !> @brief Central routine for adjoint transport of moisture fields. - !> @param[in,out] mr_out ACTIVE Perturbation to moisture mixing ratios - !> @param[in,out] mr_in ACTIVE Input perturbation state for moisture - !> @param[in] ls_mr_in PASSIVE Lin. state for moisture mixing ratios - !> @param[in] nummr_to_transport Number of moisture species to transport - !> @param[in,out] tl_transport_controller - !! Object controlling transport - !> @param[in,out] transport_metadata - !! Contains the configuration options for - !! transporting these fields + !> @param[in,out] mr_out ACTIVE Perturbation to moisture mixing ratios + !> @param[in,out] mr_in ACTIVE Input perturbation state for moisture + !> @param[in] ls_mr_in PASSIVE Lin. state for moisture mixing ratios + !> @param[in] nummr_to_transport Number of moisture species to transport + !> @param[in,out] tl_transport_controller Object controlling transport + !> @param[in,out] transport_metadata Contains the configuration options for + !! transporting these fields + !> @param[in] adj_lookup_table_cache Lookup table cache subroutine atl_moist_mr_transport_alg( mr_out, mr_in, ls_mr_in, & nummr_to_transport, & tl_transport_controller, & - transport_metadata ) + transport_metadata, & + adj_lookup_table_cache ) implicit none ! Arguments type(field_type), intent(inout) :: mr_out(nummr) type(field_type), intent(inout) :: mr_in(nummr) - type(field_type), intent(in) :: ls_mr_in(nummr) - integer(kind=i_def), intent(in) :: nummr_to_transport + type(field_type), intent(in) :: ls_mr_in(nummr) + integer(kind=i_def), intent(in) :: nummr_to_transport type(tl_transport_controller_type), intent(inout) :: tl_transport_controller type(transport_metadata_type), intent(inout) :: transport_metadata + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables integer(kind=i_def) :: imr + integer(tik) :: id - if ( subroutine_timers ) call timer('atl moist mixing ratio transport') + if ( LPROF ) call start_timing( id, 'atl_mois_mixing_ratio_transport' ) ! ------------------------------------------------------------------------ ! ! Copy non-transported fields over @@ -79,7 +82,8 @@ contains ! Simply transport all the mixing ratio fields as they are in Wtheta do imr = nummr_to_transport, 1, -1 call atl_transport_field( mr_out(imr), mr_in(imr), ls_mr_in(imr), & - tl_transport_controller, transport_metadata ) + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) end do ! ------------------------------------------------------------------------ ! @@ -98,8 +102,7 @@ contains end select - - if ( subroutine_timers ) call timer('atl moist mixing ratio transport') + if ( LPROF ) call stop_timing( id, 'atl_mois_mixing_ratio_transport' ) end subroutine atl_moist_mr_transport_alg diff --git a/science/adjoint/source/algorithm/transport/control/atl_split_transport_mod.x90 b/science/adjoint/source/algorithm/transport/control/atl_split_transport_mod.x90 new file mode 100644 index 000000000..1019d840a --- /dev/null +++ b/science/adjoint/source/algorithm/transport/control/atl_split_transport_mod.x90 @@ -0,0 +1,338 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief Adjoint of the tangent linear version of split_transport + +module atl_split_transport_mod + + use constants_mod, only: i_def, r_tran + use r_tran_field_mod, only: r_tran_field_type + use log_mod, only: log_event, LOG_LEVEL_ERROR + use split_transport_utils_mod, only: get_splitting_direction, & + get_splitting_fraction, & + get_num_split_steps + use split_transport_mod, only: split_transport_field + + ! Transport control infrastructure + use transport_controller_mod, only: transport_controller_type + use tl_transport_controller_mod, only: tl_transport_controller_type + use transport_counter_mod, only: transport_counter_type + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type + use transport_enumerated_types_mod, only: direction_h, & + direction_v, & + split_method_null, & + split_method_mol, & + split_method_ffsl, & + split_method_sl, & + equation_form_conservative, & + equation_form_advective, & + equation_form_consistent + use transport_metadata_mod, only: transport_metadata_type + + ! Algorithms + use end_of_transport_step_alg_mod, only: end_of_conservative_step_alg, & + end_of_consistent_step_alg, & + end_of_advective_step_alg + use linear_config_mod, only: transport_efficiency + + implicit none + + private + + public :: atl_split_transport_control + public :: atl_split_transport_field + +contains + + !============================================================================= + !> @brief Controls vertical/horizontal split transport. + !> @details Manages the vertical/horizontal splitting of the split transport + !! scheme by choosing the splitting type and calling the individual + !! vertical and horizontal split components. + !> @param[in,out] field_np1 ACTIVE Field to return at end + !> @param[in,out] field_n ACTIVE Field at the start + !> @param[in] ls_field_n PASSIVE LS Field at the start + !> @param[in,out] tl_transport_controller Encapsulating object containing the + !! transport counter and precomputations + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atl_split_transport_control(field_np1, field_n, ls_field_n, & + tl_transport_controller, adj_lookup_table_cache) + + implicit none + + ! Arguments + type(r_tran_field_type), intent(inout) :: field_np1 + type(r_tran_field_type), target, intent(inout) :: field_n + type(r_tran_field_type), target, intent(in) :: ls_field_n + type(tl_transport_controller_type), intent(inout) :: tl_transport_controller + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache + + ! Internal variables + integer(kind=i_def) :: num_split_steps + integer(kind=i_def) :: split_step_count + type(r_tran_field_type), allocatable :: ls_field_np1(:) + type(r_tran_field_type), target :: field_tmp + type(r_tran_field_type), pointer :: field_ptr + type(transport_counter_type), pointer :: transport_counter + type(transport_counter_type), pointer :: ls_transport_counter + type(transport_metadata_type), pointer :: transport_metadata + type(transport_controller_type), pointer :: pert_transport_controller + type(transport_controller_type), pointer :: ls_transport_controller + real(kind=r_tran) :: dt_substep + integer(kind=i_def) :: num_substeps + + ! ------------------------------------------------------------------------ ! + ! NONLINEAR (LS) + ! ------------------------------------------------------------------------ ! + + ls_transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() + transport_metadata => ls_transport_controller%get_transport_metadata() + ls_transport_counter => ls_transport_controller%get_transport_counter() + + ! Initialise fields + num_split_steps = get_num_split_steps(transport_metadata%get_splitting()) + allocate(ls_field_np1(num_split_steps + 1)) + do split_step_count = 1, num_split_steps + 1 + call field_n%copy_field_properties(ls_field_np1(split_step_count)) + end do + + if ( .not. transport_efficiency ) then + + ! When we have multiple split steps, we need an intermediate field for the + ! field at the start of each substep + ! field_ptr points to the field at the start of each split step + call invoke( setval_X(ls_field_np1(1), ls_field_n) ) + + if (num_split_steps > 1) then + call field_n%copy_field_properties(field_tmp) + call invoke( setval_X(field_tmp, ls_field_n) ) + field_ptr => field_tmp + else + field_ptr => ls_field_n + end if + + do split_step_count = 1, num_split_steps + call split_transport_field( ls_field_np1(split_step_count+1), & + field_ptr, & + ls_transport_controller & + ) + + if (split_step_count < num_split_steps) then + call invoke( setval_X(field_tmp, ls_field_np1(split_step_count+1) ) ) + + ! Increment split step counter + call ls_transport_counter%inc_split_step_counter() + end if + end do + else + do split_step_count = 1, num_split_steps + 1 + call invoke( setval_X(ls_field_np1(split_step_count), ls_field_n) ) + end do + end if + + ! ------------------------------------------------------------------------ ! + ! LINEAR + ! ------------------------------------------------------------------------ ! + pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_metadata => pert_transport_controller%get_transport_metadata() + transport_counter => pert_transport_controller%get_transport_counter() + + dt_substep = transport_counter%get_dt_substep() + num_substeps = transport_counter%get_num_substeps() + call transport_counter%adj_initialise(transport_metadata, dt_substep, num_substeps ) + call ls_transport_counter%adj_initialise(transport_metadata, dt_substep, num_substeps ) + + ! Initialise fields + num_split_steps = get_num_split_steps(transport_metadata%get_splitting()) + + call field_n%copy_field_properties(field_tmp) + + ! Set fields to zero + call invoke( setval_C(field_tmp, 0.0_r_def ) ) + + ! Loop backwards + do split_step_count = num_split_steps, 1, -1 + + if (split_step_count < num_split_steps) then + + ! Increment split step counter + call transport_counter%dec_split_step_counter() + call ls_transport_counter%dec_split_step_counter() + + call invoke( inc_X_plus_Y(field_np1, field_tmp ), & + setval_C(field_tmp, 0.0_r_def ) ) + + end if + + call atl_split_transport_field( & + field_np1, field_tmp, ls_field_np1(split_step_count), & + tl_transport_controller, adj_lookup_table_cache & + ) + call invoke( setval_C(field_np1, 0.0_r_def ) ) + + end do + if (num_split_steps <= 1) then + call invoke( setval_C(field_np1, 0.0_r_def ) ) + end if + call invoke( inc_X_plus_Y(field_n, field_tmp) ) + + deallocate( ls_field_np1 ) + + end subroutine atl_split_transport_control + + !============================================================================= + !> @brief Does either vertical or horizontal transport of a field. + !> @details Performs a vertical or horizontal transport step, solving the + !! transport equation for a (multidata) field. + !> @param[in,out] field_np1 ACTIVE Field to return at end + !> @param[in,out] field_n ACTIVE Field at the start + !> @param[in] ls_field_n PASSIVE Field at the start + !> @param[in,out] tl_transport_controller Encapsulating object containing the + !! transport counter and precomputations + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atl_split_transport_field(field_np1, field_n, ls_field_n, & + tl_transport_controller, adj_lookup_table_cache) + + use atl_mol_conservative_alg_mod, only: atl_mol_conservative_alg + use atl_mol_advective_alg_mod, only: atl_mol_advective_alg + + implicit none + + ! Arguments + type(r_tran_field_type), intent(inout) :: field_np1 + type(r_tran_field_type), intent(inout) :: field_n + type(r_tran_field_type), intent(in) :: ls_field_n + type(tl_transport_controller_type), intent(inout) :: tl_transport_controller + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache + + ! Internal variables + integer(kind=i_def) :: method, direction + type(transport_counter_type), pointer :: transport_counter + type(transport_metadata_type), pointer :: transport_metadata + type(transport_controller_type), pointer :: pert_transport_controller + + pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_counter => pert_transport_controller%get_transport_counter() + transport_metadata => pert_transport_controller%get_transport_metadata() + + ! -------------------------------------------------------------------------! + ! Set up method based on direction + ! -------------------------------------------------------------------------! + direction = get_splitting_direction( & + transport_metadata%get_splitting(), & + transport_counter%get_split_step_of_substep_counter() & + ) + + select case ( direction ) + case ( direction_h ) + method = transport_metadata%get_horizontal_method() + case ( direction_v ) + method = transport_metadata%get_vertical_method() + case default + call log_event('Split transport direction not recognised', LOG_LEVEL_ERROR) + end select + + ! -------------------------------------------------------------------------! + ! Choose method, and then choose equation + ! -------------------------------------------------------------------------! + select case ( method ) + + ! -------------------------------------------------------------------------! + ! Null step + ! -------------------------------------------------------------------------! + case ( split_method_null ) + call log_event( & + 'ADJ: Split method null not coded', & + LOG_LEVEL_ERROR & + ) + + ! -------------------------------------------------------------------------! + ! Method of Lines step + ! -------------------------------------------------------------------------! + case ( split_method_mol ) + ! Choose form of transport equation + select case ( transport_metadata%get_equation_form() ) + case ( equation_form_conservative ) + call atl_mol_conservative_alg( & + field_np1, field_n, ls_field_n, tl_transport_controller, adj_lookup_table_cache & + ) + case ( equation_form_advective ) + call atl_mol_advective_alg( & + field_np1, field_n, ls_field_n, tl_transport_controller, adj_lookup_table_cache & + ) + case ( equation_form_consistent ) + call log_event( & + 'ADJ: MoL Consistent not coded yet', & + LOG_LEVEL_ERROR & + ) + case default + call log_event( & + 'Trying to solve unrecognised form of transport equation', & + LOG_LEVEL_ERROR & + ) + + end select + + ! -------------------------------------------------------------------------! + ! Flux-Form Semi-Lagrangian step + ! -------------------------------------------------------------------------! + case ( split_method_ffsl ) + ! All equation forms have the same control method + call log_event( & + 'ADJ: FFSL not coded yet', & + LOG_LEVEL_ERROR & + ) + ! -------------------------------------------------------------------------! + ! Semi-Lagrangian step + ! -------------------------------------------------------------------------! + case ( split_method_sl ) + ! Choose direction + select case ( direction ) + + case ( direction_h ) + ! Horizontal SL only for advective form + if ( transport_metadata%get_equation_form() /= equation_form_advective ) then + call log_event( & + 'Horizontal semi-Lagrangian is only for advective form', & + LOG_LEVEL_ERROR & + ) + end if + call log_event( & + 'ADJ: Horizontal SL not coded yet', & + LOG_LEVEL_ERROR & + ) + + case ( direction_v ) + ! Choose form of transport equation for vertical + select case ( transport_metadata%get_equation_form() ) + + case ( equation_form_conservative ) + call log_event( & + 'TL: Vertical SL conservative not coded yet', & + LOG_LEVEL_ERROR & + ) + case ( equation_form_advective ) + call log_event( & + 'ADJ: Vertical SL advective not coded yet', & + LOG_LEVEL_ERROR & + ) + case default + call log_event( & + 'Trying to solve unrecognised form of transport equation', & + LOG_LEVEL_ERROR & + ) + end select + end select + + case default + call log_event( & + 'Trying to transport with unrecognised scheme', & + LOG_LEVEL_ERROR & + ) + end select + + end subroutine atl_split_transport_field + +end module atl_split_transport_mod diff --git a/science/adjoint/source/algorithm/transport/control/atl_theta_transport_alg_mod.x90 b/science/adjoint/source/algorithm/transport/control/atl_theta_transport_alg_mod.x90 index d4e2c7337..510a17d82 100644 --- a/science/adjoint/source/algorithm/transport/control/atl_theta_transport_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/control/atl_theta_transport_alg_mod.x90 @@ -16,6 +16,7 @@ module atl_theta_transport_alg_mod theta_variable_dry, & adjust_theta use tl_transport_controller_mod, only: tl_transport_controller_type + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use transport_enumerated_types_mod, only: equation_form_advective, & equation_form_consistent use transport_metadata_mod, only: transport_metadata_type @@ -30,21 +31,22 @@ contains !============================================================================= !> @brief Adjoint routine for transporting potential temperature field. - !> @param[in,out] theta_out Perturbation: Dry potential temperature - !! after transport - !> @param[in,out] theta_inc Perturbation: Dry potential temperature - !! increment - !> @param[in,out] theta_in Perturbation: Dry potential temperature - !! before transport - !> @param[in] ls_theta_in Linear state: Dry potential temperature - !! before transport - !> @param[in,out] tl_transport_controller - !! Controls transport - !> @param[in,out] transport_metadata Contains the configuration options for - !! transporting the potential temperature - subroutine atl_theta_transport_alg( theta_out, theta_inc, & - theta_in, ls_theta_in, & - tl_transport_controller, transport_metadata ) + !> @param[in,out] theta_out Perturbation: Dry potential temperature + !! after transport + !> @param[in,out] theta_inc Perturbation: Dry potential temperature + !! increment + !> @param[in,out] theta_in Perturbation: Dry potential temperature + !! before transport + !> @param[in] ls_theta_in Linear state: Dry potential temperature + !! before transport + !> @param[in,out] tl_transport_controller Controls transport + !> @param[in,out] transport_metadata Contains the configuration options for + !! transporting the potential temperature + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atl_theta_transport_alg( theta_out, theta_inc, & + theta_in, ls_theta_in, & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) implicit none @@ -52,9 +54,10 @@ contains type(field_type), target, intent(inout) :: theta_out type(field_type), intent(inout) :: theta_inc type(field_type), target, intent(inout) :: theta_in - type(field_type), target, intent(in) :: ls_theta_in + type(field_type), target, intent(in) :: ls_theta_in type(tl_transport_controller_type), intent(inout) :: tl_transport_controller type(transport_metadata_type), intent(inout) :: transport_metadata + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables real(kind=r_def) :: one @@ -124,7 +127,8 @@ contains ! Consistent: Transformation to densities and evaluation of fluxes is in ! lowest level algorithms, so just call transport_field call atl_transport_field( theta_out_ptr, theta_in_ptr, ls_theta_in_ptr, & - tl_transport_controller, transport_metadata ) + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) ! ------------------------------------------------------------------------ ! ! Default form of transport equation diff --git a/science/adjoint/source/algorithm/transport/control/atl_transport_control_alg_mod.x90 b/science/adjoint/source/algorithm/transport/control/atl_transport_control_alg_mod.x90 index f87b4ca55..73689427d 100644 --- a/science/adjoint/source/algorithm/transport/control/atl_transport_control_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/control/atl_transport_control_alg_mod.x90 @@ -19,6 +19,7 @@ module atl_transport_control_alg_mod use model_clock_mod, only: model_clock_type use transport_config_mod, only: cheap_update use tl_transport_controller_mod, only: tl_transport_controller_type + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use transport_controller_mod, only: transport_controller_type use flux_precomputations_alg_mod, only: flux_precomputations_type use wind_precomputations_alg_mod, only: wind_precomputations_type @@ -41,25 +42,26 @@ contains !============================================================================= !> @brief Adjoint of advection of prognostic variables for the tangent linear model. - !> @param[in,out] advection_inc ACTIVE Advection increment of the dynamics - !! prognostics [u, rho, theta, exner] - !> @param[in,out] advected_fields ACTIVE Fields to advect: [u, rho, theta, exner] - !> @param[in,out] wind_np1 ACTIVE End of timestep wind field - !> @param[in,out] wind_n ACTIVE Start of timestep wind field - !> @param[in,out] mr_out ACTIVE Moisture fields after transport - !> @param[in,out] mr_in ACTIVE Moisture fields before transport - !> @param[in] ls_advected_fields PASSIVE Fields to advect: [u, rho, theta, exner] - !> @param[in] ls_wind_np1 PASSIVE End of timestep wind field - !> @param[in] ls_wind_n PASSIVE Start of timestep wind field - !> @param[in] ls_mr_in PASSIVE Moisture fields before transport - !> @param[in] model_clock Time within the model - !> @param[in] outer Outer (advection) iteration number + !> @param[in,out] advection_inc ACTIVE Advection increment of the dynamics + !! prognostics [u, rho, theta, exner] + !> @param[in,out] advected_fields ACTIVE Fields to advect: [u, rho, theta, exner] + !> @param[in,out] wind_np1 ACTIVE End of timestep wind field + !> @param[in,out] wind_n ACTIVE Start of timestep wind field + !> @param[in,out] mr_out ACTIVE Moisture fields after transport + !> @param[in,out] mr_in ACTIVE Moisture fields before transport + !> @param[in] ls_advected_fields PASSIVE Fields to advect: [u, rho, theta, exner] + !> @param[in] ls_wind_np1 PASSIVE End of timestep wind field + !> @param[in] ls_wind_n PASSIVE Start of timestep wind field + !> @param[in] ls_mr_in PASSIVE Moisture fields before transport + !> @param[in] model_clock Time within the model + !> @param[in] outer Outer (advection) iteration number + !> @param[in] adj_lookup_table_cache Lookup table cache !> subroutine atl_transport_control_alg(advection_inc, advected_fields, & wind_np1, wind_n, mr_out, mr_in, & ls_advected_fields, & ls_wind_np1, ls_wind_n, ls_mr_in, & - model_clock, outer ) + model_clock, outer, adj_lookup_table_cache ) use derived_config_mod, only: bundle_size use sci_field_bundle_builtins_mod, only: clone_bundle, set_bundle_scalar @@ -74,24 +76,25 @@ contains use adj_flux_precomputations_mod, only: adj_flux_precomputations_initialiser use adj_wind_precomputations_alg_mod, only: adj_wind_precomputations_initialiser use atl_transport_controller_mod, only: atl_transport_controller_initialiser - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none ! Arguments - type(field_type), intent(inout) :: advection_inc(bundle_size) - type(field_type), intent(inout) :: advected_fields(bundle_size) - type(field_type), intent(inout) :: wind_np1 - type(field_type), intent(inout) :: wind_n - type(field_type), intent(in) :: ls_wind_np1 - type(field_type), intent(in) :: ls_wind_n - type(field_type), intent(inout) :: mr_out(nummr) - type(field_type), intent(inout) :: mr_in(nummr) - type(field_type), intent(in) :: ls_advected_fields(bundle_size) - type(field_type), intent(in) :: ls_mr_in(nummr) - class(model_clock_type), intent(in) :: model_clock - integer(kind=i_def), intent(in) :: outer + type(field_type), intent(inout) :: advection_inc(bundle_size) + type(field_type), intent(inout) :: advected_fields(bundle_size) + type(field_type), intent(inout) :: wind_np1 + type(field_type), intent(inout) :: wind_n + type(field_type), intent(in) :: ls_wind_np1 + type(field_type), intent(in) :: ls_wind_n + type(field_type), intent(inout) :: mr_out(nummr) + type(field_type), intent(inout) :: mr_in(nummr) + type(field_type), intent(in) :: ls_advected_fields(bundle_size) + type(field_type), intent(in) :: ls_mr_in(nummr) + class(model_clock_type), intent(in) :: model_clock + integer(kind=i_def), intent(in) :: outer + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables type(field_type) :: fields_np1(bundle_size) @@ -110,8 +113,9 @@ contains type(transport_controller_type), pointer :: ls_wind_pert_rho_controller type(flux_precomputations_type), pointer :: ls_wind_pert_rho_flux_pc type(r_tran_field_type), pointer :: ref_field_rtran + integer(tik) :: id - if ( subroutine_timers ) call timer('atl_transport_control') + if ( LPROF ) call start_timing( id, 'atl_transport_control' ) ! ========================================================================= ! ! Pre-transport initialisation tasks @@ -169,7 +173,7 @@ contains call atl_theta_transport_alg( & fields_np1(igh_t), advection_inc(igh_t), advected_fields(igh_t), & ls_advected_fields(igh_t), tl_transport_controller, & - transport_metadata & + transport_metadata, adj_lookup_table_cache & ) ! ------------------------------------------------------------------------- ! @@ -190,7 +194,8 @@ contains call atl_moist_mr_transport_alg( & mr_out, mr_in, ls_mr_in, nummr_to_transport, & - tl_transport_controller, transport_metadata & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache & ) end if @@ -214,7 +219,7 @@ contains call atl_wind_transport_alg( & advection_inc(igh_u), advected_fields(igh_u), & ls_advected_fields(igh_u), tl_transport_controller, & - transport_metadata & + transport_metadata, adj_lookup_table_cache & ) ! We don't change advection_inc(igh_u) as tl_wind_transport_alg ! already returns weak increment @@ -239,7 +244,7 @@ contains call atl_transport_field( & fields_np1(igh_d), advected_fields(igh_d), & ls_advected_fields(igh_d), tl_transport_controller, & - transport_metadata & + transport_metadata, adj_lookup_table_cache & ) ! The precomputation initialisation routines are initially called on @@ -271,7 +276,7 @@ contains call tl_transport_controller%finalise() - if ( subroutine_timers ) call timer('atl_transport_control') + if ( LPROF ) call stop_timing( id, 'atl_transport_control' ) end subroutine atl_transport_control_alg diff --git a/science/adjoint/source/algorithm/transport/control/atl_transport_field_mod.f90 b/science/adjoint/source/algorithm/transport/control/atl_transport_field_mod.f90 index a00c2ee0b..a755b961c 100644 --- a/science/adjoint/source/algorithm/transport/control/atl_transport_field_mod.f90 +++ b/science/adjoint/source/algorithm/transport/control/atl_transport_field_mod.f90 @@ -18,8 +18,10 @@ module atl_transport_field_mod direction_3d, & equation_form_conservative, & equation_form_advective + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use atl_mol_conservative_alg_mod, only: atl_mol_conservative_alg use atl_mol_advective_alg_mod, only: atl_mol_advective_alg + use atl_split_transport_mod, only: atl_split_transport_control use transport_controller_mod, only: transport_controller_type use tl_transport_controller_mod, only: tl_transport_controller_type use transport_counter_mod, only: transport_counter_type @@ -34,15 +36,16 @@ module atl_transport_field_mod !============================================================================= !> @brief Adjoint of central routine for transporting fields in tangent-linear field. - !> @param[in,out] field_np1 ACTIVE Field to return at end of transport step - !> @param[in,out] field_n ACTIVE Field at the start of the transport step - !> @param[in] ls_field_n PASSIVE Linear field at the start of step - !> @param[in,out] tl_transport_controller - !! Object controlling transport by perturbed wind - !> @param[in] transport_metadata Contains the configuration options for - !! transporting these fields - subroutine atl_transport_field(field_np1, field_n, ls_field_n, & - tl_transport_controller, transport_metadata) + !> @param[in,out] field_np1 ACTIVE Field to return at end of transport step + !> @param[in,out] field_n ACTIVE Field at the start of the transport step + !> @param[in] ls_field_n PASSIVE Linear field at the start of step + !> @param[in,out] tl_transport_controller Object controlling transport by perturbed wind + !> @param[in] transport_metadata Contains the configuration options for + !! transporting these fields + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atl_transport_field(field_np1, field_n, ls_field_n, & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache) implicit none @@ -52,6 +55,7 @@ subroutine atl_transport_field(field_np1, field_n, ls_field_n, & type(field_type), intent(in) :: ls_field_n type(tl_transport_controller_type), intent(inout) :: tl_transport_controller type(transport_metadata_type), intent(inout) :: transport_metadata + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables type(transport_counter_type), pointer :: transport_counter @@ -86,13 +90,13 @@ subroutine atl_transport_field(field_np1, field_n, ls_field_n, & ! Choose form of transport equation select case ( transport_metadata%get_equation_form() ) case ( equation_form_conservative ) - call atl_mol_conservative_alg( & - field_np1, field_n, ls_field_n, tl_transport_controller & + call atl_mol_conservative_alg( & + field_np1, field_n, ls_field_n, tl_transport_controller, adj_lookup_table_cache & ) case ( equation_form_advective ) - call atl_mol_advective_alg( & - field_np1, field_n, ls_field_n, tl_transport_controller & + call atl_mol_advective_alg( & + field_np1, field_n, ls_field_n, tl_transport_controller, adj_lookup_table_cache & ) case default @@ -112,8 +116,8 @@ subroutine atl_transport_field(field_np1, field_n, ls_field_n, & ! Some split horizontal/vertical transport scheme ! -------------------------------------------------------------------------! case ( scheme_split ) - call log_event('Split transport not implemented for tangent-linear app', & - LOG_LEVEL_ERROR) + call atl_split_transport_control(field_np1, field_n, ls_field_n, & + tl_transport_controller, adj_lookup_table_cache) case default call log_event('Trying to transport with unrecognised scheme', & diff --git a/science/adjoint/source/algorithm/transport/control/atl_wind_transport_alg_mod.x90 b/science/adjoint/source/algorithm/transport/control/atl_wind_transport_alg_mod.x90 index 2e8ac21cd..6f151b626 100644 --- a/science/adjoint/source/algorithm/transport/control/atl_wind_transport_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/control/atl_wind_transport_alg_mod.x90 @@ -20,7 +20,6 @@ module atl_wind_transport_alg_mod use function_space_mod, only: function_space_type use function_space_collection_mod, only: function_space_collection use sci_geometric_constants_mod, only: get_coordinates, get_panel_id - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO @@ -29,10 +28,12 @@ module atl_wind_transport_alg_mod get_project_zdot_to_w2 use mesh_mod, only: mesh_type use operator_mod, only: operator_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_enumerated_types_mod, only: equation_form_advective use transport_config_mod, only: broken_w2_projection use tl_transport_controller_mod, only: tl_transport_controller_type + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use atl_transport_field_mod, only: atl_transport_field use transport_metadata_mod, only: transport_metadata_type use sci_field_minmax_alg_mod, only: log_field_minmax @@ -47,18 +48,19 @@ contains !============================================================================= !> @brief Central routine for adjoint transport of the wind field. - !> @param[in,out] rhs_u ACTIVE Right-hand-side for weak wind transport - !! equation. In other words, the advective - !! increment to the wind multiplied by the - !! W2 mass matrix. - !> @param[in,out] wind_n ACTIVE Wind field at start of transport step - !> @param[in] ls_wind_n PASSIVE Wind field at start of transport step - !> @param[in,out] tl_transport_controller - !! Object controlling transport - !> @param[in,out] transport_metadata Contains the configuration options for - !! transporting these fields - subroutine atl_wind_transport_alg( rhs_u, wind_n, ls_wind_n, & - tl_transport_controller, transport_metadata ) + !> @param[in,out] rhs_u ACTIVE Right-hand-side for weak wind transport + !! equation. In other words, the advective + !! increment to the wind multiplied by the + !! W2 mass matrix. + !> @param[in,out] wind_n ACTIVE Wind field at start of transport step + !> @param[in] ls_wind_n PASSIVE Wind field at start of transport step + !> @param[in,out] tl_transport_controller Object controlling transport + !> @param[in,out] transport_metadata Contains the configuration options for + !! transporting these fields + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atl_wind_transport_alg( rhs_u, wind_n, ls_wind_n, & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) use sci_dg_convert_hdiv_field_kernel_mod, only: dg_convert_hdiv_field_kernel_type use invoke_adj_cvt_hdiv_field_kernel_mod, only: invoke_adj_convert_hdiv_field_kernel @@ -72,9 +74,10 @@ contains ! Arguments type(field_type), intent(inout) :: rhs_u type(field_type), intent(inout) :: wind_n - type(field_type), intent(in) :: ls_wind_n + type(field_type), intent(in) :: ls_wind_n type(tl_transport_controller_type), intent(inout) :: tl_transport_controller type(transport_metadata_type), intent(inout) :: transport_metadata + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables integer(kind=i_def) :: dir @@ -93,8 +96,9 @@ contains type(function_space_type), pointer :: w3_fs type(function_space_type), pointer :: w2_fs type(function_space_type), pointer :: w2b_fs + integer(tik) :: id - if ( subroutine_timers ) call timer('atl wind transport') + if ( LPROF ) call start_timing( id, 'atl_wind_transport' ) ! ------------------------------------------------------------------------ ! ! Semi-implicit formulation @@ -196,8 +200,9 @@ contains ! Transport wind components in W3 ! -------------------------------------------------------------------- ! do dir = 3, 1, -1 - call atl_transport_field( u_w3_np1(dir), u_w3_n(dir), ls_u_w3_n(dir), & - tl_transport_controller, transport_metadata ) + call atl_transport_field( u_w3_np1(dir), u_w3_n(dir), ls_u_w3_n(dir), & + tl_transport_controller, transport_metadata, & + adj_lookup_table_cache ) end do ! Perturbation part @@ -214,7 +219,7 @@ contains end if ! si_momentum_equation - if ( subroutine_timers ) call timer('atl wind transport') + if ( LPROF ) call stop_timing( id, 'atl_wind_transport' ) end subroutine atl_wind_transport_alg diff --git a/science/adjoint/source/algorithm/transport/mol/adj_reconstruct_w3_field_alg_mod.x90 b/science/adjoint/source/algorithm/transport/mol/adj_reconstruct_w3_field_alg_mod.x90 index b0bac45cf..f81998a06 100644 --- a/science/adjoint/source/algorithm/transport/mol/adj_reconstruct_w3_field_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/mol/adj_reconstruct_w3_field_alg_mod.x90 @@ -7,14 +7,12 @@ !> @brief Adjoint reconstruction of a W3 field at W2 points for use in the transport scheme. module adj_reconstruct_w3_field_alg_mod - use check_configuration_mod, only: get_required_stencil_depth use constants_mod, only: r_tran, i_def, l_def use r_tran_field_mod, only: r_tran_field_type use invoke_adj_poly1d_recon_lookup_mod, only: invoke_adj_poly1d_recon_lookup use invoke_adj_poly2d_recon_lookup_mod, only: invoke_adj_poly2d_recon_lookup - use adj_lookup_table_generators_alg_mod, only: create_lookup_poly1d, & - create_lookup_poly2d + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use adj_lookup_table_mod, only: adj_lookup_table_type use integer_field_mod, only: integer_field_type use function_space_mod, only: function_space_type @@ -40,23 +38,25 @@ contains !============================================================================= !> @brief Adjoint of reconstruction of a W3 field in the horizontal component of W2 - !> @param[in,out] field_new The resulting horizontal W2 field - !> @param[in,out] field_old The input W3 field - !> @param[in] transport_metadata Contains transport configuration options + !> @param[in,out] field_new The resulting horizontal W2 field + !> @param[in,out] field_old The input W3 field + !> @param[in] transport_metadata Contains transport configuration options + !> @param[in] adj_lookup_table_cache Lookup table cache subroutine adj_hori_w3_reconstruct_alg( field_new, field_old, & - transport_metadata ) + transport_metadata, adj_lookup_table_cache ) implicit none - type(r_tran_field_type), intent(inout) :: field_new - type(r_tran_field_type), intent(inout) :: field_old - type(transport_metadata_type), intent(in) :: transport_metadata + type(r_tran_field_type), intent(inout) :: field_new + type(r_tran_field_type), intent(inout) :: field_old + type(transport_metadata_type), intent(in) :: transport_metadata + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache - type(mesh_type), pointer :: mesh - integer(kind=i_def) :: mesh_id - integer(kind=i_def) :: stencil_extent - integer(kind=i_def) :: stencil_size - type(r_tran_field_type), pointer :: flux_coeffs + type(mesh_type), pointer :: mesh + integer(kind=i_def) :: mesh_id + integer(kind=i_def) :: stencil_extent + integer(kind=i_def) :: stencil_size + type(r_tran_field_type), pointer :: flux_coeffs type(r_tran_field_type), target :: remap_field, field_old_big_halo type(r_tran_field_type), pointer :: field_ptr @@ -64,14 +64,14 @@ contains logical(kind=l_def) :: monotone integer(kind=i_def) :: remap_depth - type(adj_lookup_table_type) :: lookup_poly - type(integer_field_type), pointer :: lookup_poly_field - type(integer_field_type), pointer :: num_sets_poly_field - integer(kind=i_def) :: nsets - integer(kind=i_def) :: nindices + type(adj_lookup_table_type), pointer :: lookup_poly + type(integer_field_type), pointer :: lookup_poly_field + type(integer_field_type), pointer :: num_sets_poly_field + integer(kind=i_def) :: nsets + integer(kind=i_def) :: nindices nullify(mesh, flux_coeffs, field_ptr, & - lookup_poly_field, num_sets_poly_field) + lookup_poly, lookup_poly_field, num_sets_poly_field) mesh => field_new%get_mesh() mesh_id = mesh%get_id() @@ -90,7 +90,7 @@ contains ! Copy field to a large halo version call field_old_big_halo%initialise( field_old%get_function_space(), & - halo_depth = get_required_stencil_depth() ) + halo_depth=mesh%get_halo_depth() ) call invoke( setval_c( field_old_big_halo, 0.0_r_tran ) ) monotone = (transport_metadata%get_horizontal_monotone() == monotone_koren) @@ -112,10 +112,7 @@ contains else if ( oned_reconstruction ) then ! Use 1d flux reconstruction - ! Create lookup table for stencil application. Essentially a dry run - ! of the TL kernel. - call create_lookup_poly1d( lookup_poly, field_new, field_ptr, & - flux_coeffs, stencil_extent, fv_horizontal_order ) + lookup_poly => adj_lookup_table_cache%get_lookup_poly1d() lookup_poly_field => lookup_poly%get_lookup_field() num_sets_poly_field => lookup_poly%get_set_count_field() nindices = lookup_poly%get_nindices() @@ -129,10 +126,7 @@ contains else ! Use 2d flux reconstruction stencil_extent = fv_horizontal_order / 2_i_def - ! Create lookup table for stencil application. Essentially a dry run - ! of the TL kernel. - call create_lookup_poly2d( lookup_poly, field_new, field_old_big_halo, flux_coeffs, & - stencil_size, stencil_extent ) + lookup_poly => adj_lookup_table_cache%get_lookup_poly2d(field_new%which_function_space()) lookup_poly_field => lookup_poly%get_lookup_field() num_sets_poly_field => lookup_poly%get_set_count_field() nindices = lookup_poly%get_nindices() diff --git a/science/adjoint/source/algorithm/transport/mol/adj_wt_advective_update_alg_mod.x90 b/science/adjoint/source/algorithm/transport/mol/adj_wt_advective_update_alg_mod.x90 index 83fa0a54f..58617ce09 100644 --- a/science/adjoint/source/algorithm/transport/mol/adj_wt_advective_update_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/mol/adj_wt_advective_update_alg_mod.x90 @@ -7,7 +7,6 @@ module adj_wt_advective_update_alg_mod - use check_configuration_mod, only : get_required_stencil_depth use constants_mod, only : r_tran, i_def, l_def use r_tran_field_mod, only : r_tran_field_type use finite_element_config_mod, only : element_order_h, & @@ -18,9 +17,7 @@ module adj_wt_advective_update_alg_mod use mesh_mod, only : mesh_type use invoke_adj_poly1d_recon_lookup_mod, only : invoke_adj_poly1d_recon_lookup - use adj_lookup_table_generators_alg_mod, only : create_lookup_poly1d, & - create_lookup_poly2d, & - create_lookup_poly_adv_upd + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use adj_lookup_table_mod, only : adj_lookup_table_type use integer_field_mod, only : integer_field_type @@ -49,20 +46,23 @@ contains !============================================================================= !> @brief Compute the adjoint of horizontal advective update of a Wtheta field. - !> @param[in,out] u_grad_f Horizontal part of u.grad(f) - !> @param[in] ls_wind Linearisation state wind field - !> @param[in] wind_dir Wind field used to determine direction in kernel - !> @param[in,out] field Wtheta field to advect - !> @param[in] transport_metadata Contains transport configuration options - subroutine adj_hori_wt_update_alg( u_grad_f, ls_wind, wind_dir, field, transport_metadata ) + !> @param[in,out] u_grad_f Horizontal part of u.grad(f) + !> @param[in] ls_wind Linearisation state wind field + !> @param[in] wind_dir Wind field used to determine direction in kernel + !> @param[in,out] field Wtheta field to advect + !> @param[in] transport_metadata Contains transport configuration options + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine adj_hori_wt_update_alg( u_grad_f, ls_wind, wind_dir, field, & + transport_metadata, adj_lookup_table_cache ) implicit none - type(r_tran_field_type), intent(inout) :: u_grad_f - type(r_tran_field_type), intent(in) :: ls_wind - type(r_tran_field_type), intent(in) :: wind_dir - type(r_tran_field_type), intent(inout) :: field - type(transport_metadata_type), intent(in) :: transport_metadata + type(r_tran_field_type), intent(inout) :: u_grad_f + type(r_tran_field_type), intent(in) :: ls_wind + type(r_tran_field_type), intent(in) :: wind_dir + type(r_tran_field_type), intent(inout) :: field + type(transport_metadata_type), intent(in) :: transport_metadata + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache type(r_tran_field_type) :: h_reconstruction type(r_tran_field_type), pointer :: adv_coeffs @@ -80,15 +80,16 @@ contains logical(kind=l_def) :: monotone integer(kind=i_def) :: remap_depth - type(adj_lookup_table_type) :: lookup_poly - type(adj_lookup_table_type) :: lookup_poly_adv - type(integer_field_type), pointer :: lookup_poly_field - type(integer_field_type), pointer :: num_sets_poly_field - integer(kind=i_def) :: nsets - integer(kind=i_def) :: nindices + type(adj_lookup_table_type), pointer :: lookup_poly + type(adj_lookup_table_type), pointer :: lookup_poly_adv + type(integer_field_type), pointer :: lookup_poly_field + type(integer_field_type), pointer :: num_sets_poly_field + integer(kind=i_def) :: nsets + integer(kind=i_def) :: nindices - nullify(lookup_poly_field, num_sets_poly_field, mesh, & - field_ptr, multidata_fs, adv_coeffs) + nullify(lookup_poly, lookup_poly_adv, & + lookup_poly_field, num_sets_poly_field, & + mesh, field_ptr, multidata_fs, adv_coeffs) mesh => ls_wind%get_mesh() mesh_id = mesh%get_id() @@ -104,7 +105,7 @@ contains ! Copy field to a large halo version call field_big_halo%initialise( field%get_function_space(), & - halo_depth = get_required_stencil_depth() ) + halo_depth=mesh%get_halo_depth() ) ! Compute reconstruction on a Wtheta multidata field ! each Wt point contains 4 values assigned to each edge, @@ -133,8 +134,7 @@ contains stencil_extent = 1_i_def ! Invoke lookup table kernel for adj_poly_adv_update. - call create_lookup_poly_adv_upd( lookup_poly_adv, u_grad_f, h_reconstruction, & - ls_wind, stencil_extent ) + lookup_poly_adv => adj_lookup_table_cache%get_lookup_poly_adv_upd() lookup_poly_field => lookup_poly_adv%get_lookup_field() num_sets_poly_field => lookup_poly_adv%get_set_count_field() nindices = lookup_poly_adv%get_nindices() @@ -151,10 +151,7 @@ contains else if ( oned_reconstruction ) then ! Use 1d reconstruction - ! create lookup table for stencil application. essentially a dry run - ! of the tl kernel. - call create_lookup_poly1d( lookup_poly, h_reconstruction, field_ptr, & - adv_coeffs, stencil_extent, fv_horizontal_order ) + lookup_poly => adj_lookup_table_cache%get_lookup_poly1d() lookup_poly_field => lookup_poly%get_lookup_field() num_sets_poly_field => lookup_poly%get_set_count_field() nindices = lookup_poly%get_nindices() @@ -165,10 +162,7 @@ contains stencil_extent) else ! Use 2d reconstruction - ! Create lookup table for stencil application. Essentially a dry run - ! of the TL kernel. - call create_lookup_poly2d( lookup_poly, h_reconstruction, field_big_halo, & - adv_coeffs, stencil_size, stencil_extent ) + lookup_poly => adj_lookup_table_cache%get_lookup_poly2d(h_reconstruction%which_function_space()) lookup_poly_field => lookup_poly%get_lookup_field() num_sets_poly_field => lookup_poly%get_set_count_field() nindices = lookup_poly%get_nindices() diff --git a/science/adjoint/source/algorithm/transport/mol/atl_advective_and_flux_alg_mod.x90 b/science/adjoint/source/algorithm/transport/mol/atl_advective_and_flux_alg_mod.x90 index 942e1d603..dcf90b453 100644 --- a/science/adjoint/source/algorithm/transport/mol/atl_advective_and_flux_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/mol/atl_advective_and_flux_alg_mod.x90 @@ -26,7 +26,7 @@ module atl_advective_and_flux_alg_mod use vertical_mass_flux_kernel_mod, only: vertical_mass_flux_kernel_type use atl_w3h_advective_update_kernel_mod, only: atl_w3h_advective_update_kernel_type use invoke_adj_w3h_adv_upd_lookup_mod, only: invoke_adj_w3h_adv_upd_lookup_kernel_type - use adj_lookup_table_generators_alg_mod, only: create_lookup_w3h_adv_upd + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use adj_lookup_table_mod, only: adj_lookup_table_type use integer_field_mod, only: integer_field_type use atl_w3v_advective_update_kernel_mod, only: atl_w3v_advective_update_kernel_type @@ -53,39 +53,42 @@ contains !============================================================================! !> @brief Computes the tangent linear flux F and advective increment !> @details Compute the tangent linear mass flux and advective increment - !> @param[in,out] mass_flux_1 ACTIVE: mass flux to compute from - !! linear wind and perturbation field - !> @param[in,out] mass_flux_2 ACTIVE: mass flux to compute from - !! perturbation wind and linear field - !> @param[in,out] adv_inc ACTIVE: advective increment to compute - !> @param[in,out] density ACTIVE: W3 field to transport - !> @param[in,out] wind ACTIVE: transporting wind field - !> @param[in] ls_density PASSIVE: linearisation transported field - !> @param[in] ls_wind PASSIVE: linearisation transporting wind - !> @param[in] direction Direction of the transport - !> @param[in] transport_metadata Contains transport configuration options - !> @param[in] final_rk_stage Whether this is the last Runge-Kutta stage - !> @param[in] dt Advection time step - !> @param[in] do_flux Flag to compute mass_flux = wind*density - !> @param[in] do_advective Flag to compute adv_inc = wind.grad(density) + !> @param[in,out] mass_flux_1 ACTIVE: mass flux to compute from + !! linear wind and perturbation field + !> @param[in,out] mass_flux_2 ACTIVE: mass flux to compute from + !! perturbation wind and linear field + !> @param[in,out] adv_inc ACTIVE: advective increment to compute + !> @param[in,out] density ACTIVE: W3 field to transport + !> @param[in,out] wind ACTIVE: transporting wind field + !> @param[in] ls_density PASSIVE: linearisation transported field + !> @param[in] ls_wind PASSIVE: linearisation transporting wind + !> @param[in] direction Direction of the transport + !> @param[in] transport_metadata Contains transport configuration options + !> @param[in] final_rk_stage Whether this is the last Runge-Kutta stage + !> @param[in] dt Advection time step + !> @param[in] do_flux Flag to compute mass_flux = wind*density + !> @param[in] do_advective Flag to compute adv_inc = wind.grad(density) + !> @param[in] adj_lookup_table_cache Lookup table cache subroutine atl_advective_and_flux_alg( mass_flux_1, mass_flux_2, adv_inc, & density, wind, ls_density, ls_wind, & direction, transport_metadata, & final_rk_stage, dt, & - do_flux, do_advective ) + do_flux, do_advective, & + adj_lookup_table_cache ) implicit none - type(field_type), intent(inout) :: mass_flux_1, mass_flux_2 - type(field_type), intent(inout) :: density, wind - type(field_type), intent(in) :: ls_density, ls_wind - type(field_type), intent(inout) :: adv_inc - integer(kind=i_def), intent(in) :: direction - type(transport_metadata_type), intent(in) :: transport_metadata - logical(kind=l_def), intent(in) :: final_rk_stage - real(kind=r_def), intent(in) :: dt - logical(kind=l_def), intent(in) :: do_flux - logical(kind=l_def), intent(in) :: do_advective + type(field_type), intent(inout) :: mass_flux_1, mass_flux_2 + type(field_type), intent(inout) :: density, wind + type(field_type), intent(in) :: ls_density, ls_wind + type(field_type), intent(inout) :: adv_inc + integer(kind=i_def), intent(in) :: direction + type(transport_metadata_type), intent(in) :: transport_metadata + logical(kind=l_def), intent(in) :: final_rk_stage + real(kind=r_def), intent(in) :: dt + logical(kind=l_def), intent(in) :: do_flux + logical(kind=l_def), intent(in) :: do_advective + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables type(field_type) :: adv_inc_1, adv_inc_2 @@ -102,13 +105,13 @@ contains type(operator_type), pointer :: m3_inv integer(kind=i_def), parameter :: stencil_depth = 1 - type(adj_lookup_table_type) :: lookup_w3h - type(integer_field_type), pointer :: lookup_w3h_field - type(integer_field_type), pointer :: set_count_w3h_field - integer(kind=i_def) :: nsets - integer(kind=i_def) :: nindices + type(adj_lookup_table_type), pointer :: lookup_w3h + type(integer_field_type), pointer :: lookup_w3h_field + type(integer_field_type), pointer :: set_count_w3h_field + integer(kind=i_def) :: nsets + integer(kind=i_def) :: nindices - nullify(mesh, recon_fs, m3_inv, lookup_w3h_field, set_count_w3h_field) + nullify(mesh, recon_fs, m3_inv, lookup_w3h, lookup_w3h_field, set_count_w3h_field) mesh => density%get_mesh() @@ -204,10 +207,7 @@ contains wind, & m3_inv ) ) - ! Lookup table adjoint solution. Creation of lookup table is essentially - ! a dry-run of the TL code. - call create_lookup_w3h_adv_upd( lookup_w3h, adv_inc_1, reconstruction_field, & - wind, m3_inv, stencil_depth ) + lookup_w3h => adj_lookup_table_cache%get_lookup_w3h_adv_upd(ls_wind%which_function_space()) lookup_w3h_field => lookup_w3h%get_lookup_field() set_count_w3h_field => lookup_w3h%get_set_count_field() nindices = lookup_w3h%get_nindices() @@ -246,8 +246,9 @@ contains end if - call atl_reconstruct_w3_field_alg( reconstruction_field, density, ls_density, & - direction, transport_metadata, final_rk_stage ) + call atl_reconstruct_w3_field_alg( reconstruction_field, density, ls_density, & + direction, transport_metadata, final_rk_stage, & + adj_lookup_table_cache ) case ( Wtheta ) if ( do_flux ) then @@ -255,8 +256,9 @@ contains end if if ( do_advective ) then - call atl_wt_advective_update_alg( adv_inc, density, wind, ls_density, ls_wind, & - dt, direction, transport_metadata, final_rk_stage ) + call atl_wt_advective_update_alg( adv_inc, density, wind, ls_density, ls_wind, & + dt, direction, transport_metadata, final_rk_stage, & + adj_lookup_table_cache ) end if case default diff --git a/science/adjoint/source/algorithm/transport/mol/atl_mol_advective_alg_mod.x90 b/science/adjoint/source/algorithm/transport/mol/atl_mol_advective_alg_mod.x90 index cec84c386..802aa9d5e 100644 --- a/science/adjoint/source/algorithm/transport/mol/atl_mol_advective_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/mol/atl_mol_advective_alg_mod.x90 @@ -13,6 +13,7 @@ module atl_mol_advective_alg_mod use mesh_mod, only: mesh_type ! Algorithms and transport code + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use advective_and_flux_alg_mod, only: advective_and_flux_alg use atl_advective_and_flux_alg_mod, only: atl_advective_and_flux_alg use end_of_transport_step_alg_mod, only: end_of_advective_step_alg @@ -27,7 +28,8 @@ module atl_mol_advective_alg_mod use wind_precomputations_alg_mod, only: wind_precomputations_type ! Configuration - use transport_config_mod, only: runge_kutta_method + use transport_config_mod, only: runge_kutta_method + use linear_config_mod, only: transport_efficiency implicit none @@ -37,14 +39,14 @@ contains !============================================================================= !> @brief Adjoint of tangent linear advection of a field with the MOL scheme. - !> @param[in,out] field_np1 ACTIVE Field at the end of the time step - !> @param[in] field ACTIVE Field at the start of the transport step - !> @param[in] ls_field PASSIVE Field at the start of the transport step - !> @param[in] direction Direction of advection (vertical, horizontal, or 3d) - !> @param[in,out] tl_transport_controller - !! Object controlling transport + !> @param[in,out] field_np1 ACTIVE Field at the end of the time step + !> @param[in] field ACTIVE Field at the start of the transport step + !> @param[in] ls_field PASSIVE Field at the start of the transport step + !> @param[in] direction Direction of advection (vertical, horizontal, or 3d) + !> @param[in,out] tl_transport_controller Object controlling transport + !> @param[in] adj_lookup_table_cache Lookup table cache subroutine atl_mol_advective_alg( field_np1, field, ls_field, & - tl_transport_controller ) + tl_transport_controller, adj_lookup_table_cache ) implicit none @@ -52,11 +54,14 @@ contains type(field_type), intent(inout) :: field type(field_type), intent(in) :: ls_field type(tl_transport_controller_type), intent(inout) :: tl_transport_controller + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables integer(kind=i_def) :: stage, s, direction integer(kind=i_def) :: nstage, substep + integer(kind=i_def) :: ls_stage, ls_nstage integer(kind=i_def) :: number_substeps + integer(kind=i_def) :: ls_number_substeps, ls_substep integer(kind=i_def) :: step integer(kind=i_def) :: splitting real(kind=r_def) :: dt_mol_substep @@ -71,7 +76,10 @@ contains type(field_type), allocatable :: rk_field(:) real(kind=r_def), allocatable :: rk_weights(:,:) type(transport_metadata_type), pointer :: transport_metadata + type(transport_metadata_type), pointer :: ls_transport_metadata type(transport_counter_type), pointer :: transport_counter + type(transport_counter_type), pointer :: ls_transport_counter + type(transport_controller_type), pointer :: transport_controller type(transport_controller_type), pointer :: ls_transport_controller type(transport_controller_type), pointer :: pert_transport_controller type(wind_precomputations_type), pointer :: ls_wind_precomputations @@ -81,10 +89,16 @@ contains ! Extract transport objects and initialise temporary fields ! ------------------------------------------------------------------------ ! mesh => field%get_mesh() + transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() ls_transport_controller => tl_transport_controller%get_ls_wind_pert_rho_controller() pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_metadata => pert_transport_controller%get_transport_metadata() + ls_transport_metadata => transport_controller%get_transport_metadata() + transport_counter => pert_transport_controller%get_transport_counter() + ls_transport_counter => transport_controller%get_transport_counter() + ls_wind_precomputations => ls_transport_controller%get_wind_precomputations() pert_wind_precomputations => pert_transport_controller%get_wind_precomputations() @@ -102,13 +116,24 @@ contains ) call get_rk_transport_weights(nstage, rk_weights, runge_kutta_method) + + if (transport_efficiency) then + ls_number_substeps = 1 + ls_nstage =1 + else + ls_number_substeps = number_substeps + ls_nstage = nstage + end if + allocate( rk_field(nstage) ) - allocate( stored_ls_field(number_substeps, nstage) ) + allocate( stored_ls_field(ls_number_substeps, ls_nstage) ) do stage = 1, nstage call rk_field(stage)%initialise(field%get_function_space()) - do substep = 1, number_substeps - call stored_ls_field(substep, stage)%initialise(field%get_function_space()) + end do + do ls_stage = 1, ls_nstage + do ls_substep = 1, ls_number_substeps + call stored_ls_field(ls_substep, ls_stage)%initialise(field%get_function_space()) end do end do call rhs_field%initialise( field%get_function_space() ) @@ -135,19 +160,23 @@ contains ! array for each substep and each RK stage to use in the perturbation !--------------------------------------------------------------------------! + if (transport_efficiency) then + call invoke( setval_X(stored_ls_field(1,1), ls_field_np1 )) + else + ! Perform the number of rk-stages and substeps required - do substep = 1, number_substeps + do substep = 1, ls_number_substeps ! Reset field_n ready for the this substep call ls_field_np1%copy_field_properties(ls_field_n) call invoke( setval_X(ls_field_n, ls_field_np1) ) - do stage = 1, nstage + do stage = 1, ls_nstage ! Store values for use in the perturbation code. This is done before ! advecting so as to pick up the correct linearisation state call invoke( setval_X(stored_ls_field(substep, stage), ls_field_np1) ) - final_rk_stage = ( stage == nstage ) + final_rk_stage = ( stage == ls_nstage ) ! Compute the field for this stage: ! rhs_field = sum(s=1,stage): a(stage,s)*field^(s) @@ -158,9 +187,9 @@ contains end do ! Compute update: rhs = u.grad(rhs_field) - call advective_and_flux_alg(dummy, rhs, rhs_field, ls_field_n, & - ls_advecting_wind, direction, & - transport_metadata, final_rk_stage, & + call advective_and_flux_alg(dummy, rhs, rhs_field, ls_field_n, & + ls_advecting_wind, direction, & + ls_transport_metadata, final_rk_stage, & dt_mol_substep, .false., .true. ) ! Update field: f = f^n - dt*rhs @@ -170,10 +199,12 @@ contains end do ! End of step: if necessary enforce min val and overwrite in blending zone - call end_of_advective_step_alg( & - ls_field_np1, ls_field_n, transport_counter, transport_metadata & + call end_of_advective_step_alg( & + ls_field_np1, ls_field_n, ls_transport_counter, ls_transport_metadata & ) + end if + ! -------------------------------------------------------------------------- ! Perturbation ! @@ -199,21 +230,32 @@ contains ! Perform the number of rk-stages and substeps required do substep = number_substeps, 1, -1 + if (transport_efficiency) then + ls_substep = 1 + else + ls_substep = substep + end if + do stage = nstage, 1, -1 + if (transport_efficiency) then + ls_stage = 1 + else + ls_stage = stage + end if + final_rk_stage = ( stage == nstage ) ! Update field: f = f^n - dt_substep*rhs call invoke( inc_X_minus_bY( rhs, dt_mol_substep, field_np1 ), & - inc_X_plus_Y( field_n, field_np1 ), & - setval_c( field_np1, 0.0_r_def ) ) + inc_X_plus_Y( field_n, field_np1 ) ) ! Compute update: rhs = u.grad(rhs_field) call atl_advective_and_flux_alg( & dummy, dummy, rhs, rhs_field, advecting_wind, & - stored_ls_field(substep, stage), ls_advecting_wind, & + stored_ls_field(ls_substep, ls_stage), ls_advecting_wind, & direction, transport_metadata, final_rk_stage, dt_mol_substep, & - .false., .true. & + .false., .true., adj_lookup_table_cache & ) do s = stage, 1, -1 @@ -222,8 +264,8 @@ contains ! Compute the field for this stage: ! rhs_field = sum(s=1,stage): a(stage,s)*field^(s) - call invoke( setval_c( rhs_field, 0.0_r_def ), & - inc_X_plus_Y( field_np1, rk_field(stage) ), & + call invoke( setval_c( rhs_field, 0.0_r_def ), & + setval_x( field_np1, rk_field(stage) ), & setval_c( rk_field(stage), 0.0_r_def ) ) end do ! stage diff --git a/science/adjoint/source/algorithm/transport/mol/atl_mol_conservative_alg_mod.x90 b/science/adjoint/source/algorithm/transport/mol/atl_mol_conservative_alg_mod.x90 index b5ed18d7e..fc9502e2d 100644 --- a/science/adjoint/source/algorithm/transport/mol/atl_mol_conservative_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/mol/atl_mol_conservative_alg_mod.x90 @@ -15,9 +15,11 @@ module atl_mol_conservative_alg_mod LOG_LEVEL_INFO use mesh_mod, only: mesh_type use operator_mod, only: operator_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Algorithms and transport code + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type use advective_and_flux_alg_mod, only: advective_and_flux_alg use atl_advective_and_flux_alg_mod, only: atl_advective_and_flux_alg use end_of_transport_step_alg_mod, only: end_of_conservative_step_alg @@ -26,7 +28,7 @@ module atl_mol_conservative_alg_mod use runge_kutta_init_mod, only: get_rk_transport_weights use split_transport_utils_mod, only: get_num_split_steps, & get_splitting_direction - use transport_constants_mod, only: get_directional_im3_div + use transport_constants_mod, only: get_directional_im3_div_r_tran use transport_controller_mod, only: transport_controller_type use tl_transport_controller_mod, only: tl_transport_controller_type use transport_counter_mod, only: transport_counter_type @@ -40,7 +42,7 @@ module atl_mol_conservative_alg_mod ! Configuration use boundaries_config_mod, only: limited_area use base_mesh_config_mod, only: topology, topology_non_periodic - use io_config_mod, only: subroutine_timers + use linear_config_mod, only: transport_efficiency use transport_config_mod, only: runge_kutta_method, & dry_field_name, & operators, & @@ -54,27 +56,30 @@ module atl_mol_conservative_alg_mod !============================================================================= !> @brief Adjoint of tangent linear transport (conservative-form) with the MOL scheme. - !> @param[in,out] field_np1 ACTIVE Field at the end of the time step - !> @param[in,out] field ACTIVE Field at the start of the transport step - !> @param[in] ls_field PASSIVE Field at the start of the transport step - !> @param[in,out] tl_transport_controller - !! Object controlling transport + !> @param[in,out] field_np1 ACTIVE Field at the end of the time step + !> @param[in,out] field ACTIVE Field at the start of the transport step + !> @param[in] ls_field PASSIVE Field at the start of the transport step + !> @param[in,out] tl_transport_controller Object controlling transport + !> @param[in] adj_lookup_table_cache Lookup table cache subroutine atl_mol_conservative_alg( field_np1, field, ls_field, & - tl_transport_controller ) + tl_transport_controller, adj_lookup_table_cache ) implicit none ! Arguments type(field_type), intent(inout) :: field_np1 type(field_type), intent(inout) :: field - type(field_type), intent(in) :: ls_field + type(field_type), intent(in) :: ls_field type(tl_transport_controller_type), intent(inout) :: tl_transport_controller + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache ! Internal variables integer(kind=i_def) :: mesh_id integer(kind=i_def) :: stage, s, direction integer(kind=i_def) :: nstage, substep - integer(kind=i_def) :: number_substeps + integer(kind=i_def) :: ls_nstage, ls_substep + integer(kind=i_def) :: ls_stage, number_substeps + integer(kind=i_def) :: ls_number_substeps integer(kind=i_def) :: step integer(kind=i_def) :: splitting real(kind=r_def) :: dt_mol_substep @@ -102,7 +107,9 @@ module atl_mol_conservative_alg_mod type(field_type), allocatable :: rk_field(:) real(kind=r_def), allocatable :: rk_weights(:,:) type(transport_metadata_type), pointer :: transport_metadata + type(transport_metadata_type), pointer :: ls_transport_metadata type(transport_counter_type), pointer :: transport_counter + type(transport_counter_type), pointer :: ls_transport_counter type(transport_controller_type), pointer :: transport_controller type(transport_controller_type), pointer :: ls_transport_controller type(transport_controller_type), pointer :: pert_transport_controller @@ -111,8 +118,9 @@ module atl_mol_conservative_alg_mod type(flux_precomputations_type), pointer :: flux_precomputations type(flux_precomputations_type), pointer :: ls_wind_flux_precomp type(flux_precomputations_type), pointer :: pert_wind_flux_precomp + integer(tik) :: id - if ( subroutine_timers ) call timer('atl_mol_conservative_alg') + if ( LPROF ) call start_timing( id, 'atl_transport.mol_conservative' ) ! ------------------------------------------------------------------------ ! ! Extract transport objects and initialise temporary fields @@ -122,11 +130,18 @@ module atl_mol_conservative_alg_mod transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() ls_transport_controller => tl_transport_controller%get_ls_wind_pert_rho_controller() pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_metadata => pert_transport_controller%get_transport_metadata() + ls_transport_metadata => transport_controller%get_transport_metadata() + transport_counter => pert_transport_controller%get_transport_counter() + ls_transport_counter => transport_controller%get_transport_counter() + flux_precomputations => transport_controller%get_flux_precomputations() + ls_wind_flux_precomp => ls_transport_controller%get_flux_precomputations() pert_wind_flux_precomp => pert_transport_controller%get_flux_precomputations() + ls_wind_precomputations => ls_transport_controller%get_wind_precomputations() pert_wind_precomputations => pert_transport_controller%get_wind_precomputations() @@ -142,16 +157,27 @@ module atl_mol_conservative_alg_mod dt_mol_substep = ls_wind_precomputations%get_dt_mol_substep( & mesh%get_id(), direction, splitting, step & ) - div => get_directional_im3_div(mesh_id, direction) + div => get_directional_im3_div_r_tran(mesh_id, direction) call get_rk_transport_weights(nstage, rk_weights, runge_kutta_method) + + if (transport_efficiency) then + ls_nstage = 1 + ls_number_substeps = 1 + else + ls_nstage = nstage + ls_number_substeps = number_substeps + end if + allocate( rk_field(nstage) ) - allocate( stored_ls_field(number_substeps,nstage) ) + allocate( stored_ls_field(ls_number_substeps,ls_nstage) ) do stage = 1, nstage call rk_field(stage)%initialise(field%get_function_space()) - do substep = 1, number_substeps - call stored_ls_field(substep, stage)%initialise(field%get_function_space()) + end do + do ls_stage = 1, ls_nstage + do ls_substep = 1, ls_number_substeps + call stored_ls_field(ls_substep, ls_stage)%initialise(field%get_function_space()) end do end do call rhs_field%initialise( field%get_function_space() ) @@ -186,20 +212,24 @@ module atl_mol_conservative_alg_mod ! This calculates the values of ls_field. These are stored as an ! array for each substep and each RK stage to use in the perturbation ! ======================================================================== ! + + if ( transport_efficiency ) then + call invoke( setval_X( stored_ls_field(1,1), ls_field_np1 ) ) + else ! ------------------------------------------------------------------------ ! ! Start of substepping loop ! ------------------------------------------------------------------------ ! - ls_substep_loop: do substep = 1, number_substeps + ls_substep_loop: do substep = 1, ls_number_substeps - final_substep = ( substep == number_substeps ) + final_substep = ( substep == ls_number_substeps ) ! Reset field_n ready for the this substep call ls_field_np1%copy_field_properties(ls_field_n) call invoke( setval_X(ls_field_n, ls_field_np1) ) - ls_stage_loop: do stage = 1, nstage + ls_stage_loop: do stage = 1, ls_nstage - final_rk_stage = ( stage == nstage ) + final_rk_stage = ( stage == ls_nstage ) ! Store values for use in the perturbation code. This is done before ! advecting so as to pick up the correct linearisation state @@ -240,7 +270,7 @@ module atl_mol_conservative_alg_mod call advective_and_flux_alg(flux_step, adv_inc, rhs_field, ls_field_n, & ls_advecting_wind, direction, & - transport_metadata, final_rk_stage, & + ls_transport_metadata, final_rk_stage, & dt_mol_substep, do_flux, do_advective) if ( do_flux ) then @@ -283,9 +313,11 @@ module atl_mol_conservative_alg_mod ! increment, and may be adjusted to enforce min value or in blending zone call end_of_conservative_step_alg( & ls_field_np1, ls_field, ls_sum_flux, flux_precomputations, & - transport_counter, transport_metadata & + ls_transport_counter, ls_transport_metadata & ) + end if + ! ======================================================================== ! ! Perturbation ! @@ -323,6 +355,12 @@ module atl_mol_conservative_alg_mod ! ------------------------------------------------------------------------ ! substep_loop: do substep = number_substeps, 1, -1 + if (transport_efficiency) then + ls_substep = 1 + else + ls_substep = substep + end if + final_substep = ( substep == number_substeps ) ! ---------------------------------------------------------------------- ! @@ -339,6 +377,12 @@ module atl_mol_conservative_alg_mod stage_loop: do stage = nstage, 1, -1 + if (transport_efficiency) then + ls_stage = 1 + else + ls_stage = stage + end if + final_rk_stage = ( stage == nstage ) ! -------------------------------------------------------------------- ! @@ -380,16 +424,15 @@ module atl_mol_conservative_alg_mod end if if ( do_advective ) then call invoke( inc_X_minus_bY( adv_inc, dt_mol_substep, field_np1 ), & - inc_X_plus_Y( field_n, field_np1 ), & - setval_c( field_np1, 0.0_r_def ) ) + inc_X_plus_Y( field_n, field_np1 ) ) end if call atl_advective_and_flux_alg( & flux_step_ls_wind, flux_step_pert_wind, adv_inc, & rhs_field, advecting_wind, & - stored_ls_field(substep,stage), ls_advecting_wind, & + stored_ls_field(ls_substep,ls_stage), ls_advecting_wind, & direction, transport_metadata, final_rk_stage, & - dt_mol_substep, do_flux, do_advective & + dt_mol_substep, do_flux, do_advective, adj_lookup_table_cache & ) do s = stage, 1, -1 @@ -398,8 +441,8 @@ module atl_mol_conservative_alg_mod ! Compute the field for this stage: ! rhs_field = sum(s=1,stage): a(stage,s)*field^(s) - call invoke( setval_c( rhs_field, 0.0_r_def ), & - inc_X_plus_Y( field_np1, rk_field(stage) ), & + call invoke( setval_c( rhs_field, 0.0_r_def ), & + setval_x( field_np1, rk_field(stage) ), & setval_c( rk_field(stage), 0.0_r_def ) ) end do stage_loop @@ -417,7 +460,7 @@ module atl_mol_conservative_alg_mod if ( allocated(rk_weights) ) deallocate(rk_weights) if ( allocated(stored_ls_field) ) deallocate(stored_ls_field) - if ( subroutine_timers ) call timer('atl_mol_conservative_alg') + if ( LPROF ) call stop_timing( id, 'atl_transport.mol_conservative' ) end subroutine atl_mol_conservative_alg diff --git a/science/adjoint/source/algorithm/transport/mol/atl_reconstruct_w3_field_alg_mod.x90 b/science/adjoint/source/algorithm/transport/mol/atl_reconstruct_w3_field_alg_mod.x90 index 7aff24650..a4bf5ff64 100644 --- a/science/adjoint/source/algorithm/transport/mol/atl_reconstruct_w3_field_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/mol/atl_reconstruct_w3_field_alg_mod.x90 @@ -52,24 +52,29 @@ contains !============================================================================= !> @brief Reconstruct a W3 field at W2 points for adjoint app. - !> @param[in,out] field_new ACTIVE Reconstructed field at W2 points - !> @param[in,out] field_old ACTIVE Initial W3 field - !> @param[in] ls_field_old PASSIVE Initial W3 field - !> @param[in] direction Splitting direction (h, v, or 3d) to - !! compute reconstruction - !> @param[in] transport_metadata Contains transport configuration options - !> @param[in] final_rk_stage Whether this is the last Runge-Kutta stage - subroutine atl_reconstruct_w3_field_alg( field_new, field_old, ls_field_old, & - direction, transport_metadata, final_rk_stage ) + !> @param[in,out] field_new ACTIVE Reconstructed field at W2 points + !> @param[in,out] field_old ACTIVE Initial W3 field + !> @param[in] ls_field_old PASSIVE Initial W3 field + !> @param[in] direction Splitting direction (h, v, or 3d) to + !! compute reconstruction + !> @param[in] transport_metadata Contains transport configuration options + !> @param[in] final_rk_stage Whether this is the last Runge-Kutta stage + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atl_reconstruct_w3_field_alg( field_new, field_old, ls_field_old, & + direction, transport_metadata, final_rk_stage, & + adj_lookup_table_cache ) + + use adj_trans_lookup_cache_mod, only: adj_trans_lookup_cache_type implicit none - type(field_type), intent(inout) :: field_old - type(field_type), intent(in) :: ls_field_old - type(field_type), intent(inout) :: field_new - integer(kind=i_def), intent(in) :: direction - type(transport_metadata_type), intent(in) :: transport_metadata - logical(kind=l_def), intent(in) :: final_rk_stage + type(field_type), intent(inout) :: field_old + type(field_type), intent(in) :: ls_field_old + type(field_type), intent(inout) :: field_new + integer(kind=i_def), intent(in) :: direction + type(transport_metadata_type), intent(in) :: transport_metadata + logical(kind=l_def), intent(in) :: final_rk_stage + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache type(mesh_type), pointer :: mesh type(field_type) :: field_new_h, field_new_v @@ -119,11 +124,11 @@ contains ls_field_old, transport_metadata, & final_rk_stage ) call adj_hori_w3_reconstruct_alg( field_new_h, field_old, & - transport_metadata ) + transport_metadata, adj_lookup_table_cache ) case ( direction_h ) call adj_hori_w3_reconstruct_alg( field_new, field_old, & - transport_metadata ) + transport_metadata, adj_lookup_table_cache ) case ( direction_v ) call atl_vert_w3_reconstruct_alg( field_new, field_old, & ls_field_old, transport_metadata, & diff --git a/science/adjoint/source/algorithm/transport/mol/atl_wt_advective_update_alg_mod.x90 b/science/adjoint/source/algorithm/transport/mol/atl_wt_advective_update_alg_mod.x90 index 09093efb6..f059c160c 100644 --- a/science/adjoint/source/algorithm/transport/mol/atl_wt_advective_update_alg_mod.x90 +++ b/science/adjoint/source/algorithm/transport/mol/atl_wt_advective_update_alg_mod.x90 @@ -48,21 +48,23 @@ contains !============================================================================= !> @brief Compute advective update of a Wtheta field for adjoint app. - !> @param[in,out] rhs ACTIVE Change in Advective increment - !> @param[in] adv_field ACTIVE Change in Field to advect - !> @param[in] wind ACTIVE Change in Advecting wind field - !> @param[in] ls_adv_field Lin state for Field to advect - !> @param[in] ls_wind Lin state for Advecting wind field - !> @param[in] dt Timestep - !> @param[in] direction Direction of the transport - !> @param[in] transport_metadata Contains transport configuration options - !> @param[in] final_rk_stage Whether this is the last Runge-Kutta stage - subroutine atl_wt_advective_update_alg( rhs, adv_field, wind, & - ls_adv_field, ls_wind, & - dt, direction, & - transport_metadata, final_rk_stage ) - - + !> @param[in,out] rhs ACTIVE Change in Advective increment + !> @param[in] adv_field ACTIVE Change in Field to advect + !> @param[in] wind ACTIVE Change in Advecting wind field + !> @param[in] ls_adv_field Lin state for Field to advect + !> @param[in] ls_wind Lin state for Advecting wind field + !> @param[in] dt Timestep + !> @param[in] direction Direction of the transport + !> @param[in] transport_metadata Contains transport configuration options + !> @param[in] final_rk_stage Whether this is the last Runge-Kutta stage + !> @param[in] adj_lookup_table_cache Lookup table cache + subroutine atl_wt_advective_update_alg( rhs, adv_field, wind, & + ls_adv_field, ls_wind, & + dt, direction, & + transport_metadata, final_rk_stage, & + adj_lookup_table_cache ) + + use adj_trans_lookup_cache_mod, only : adj_trans_lookup_cache_type use reference_element_mod, only : reference_element_type use mesh_mod, only : mesh_type use adj_wt_advective_update_alg_mod, only : adj_hori_wt_update_alg @@ -70,13 +72,14 @@ contains implicit none - type(field_type), intent(inout) :: adv_field, wind - type(field_type), intent(in) :: ls_adv_field, ls_wind - type(field_type), intent(inout) :: rhs - real(kind=r_def), intent(in) :: dt - integer(kind=i_def), intent(in) :: direction - type(transport_metadata_type), intent(in) :: transport_metadata - logical(kind=l_def), intent(in) :: final_rk_stage + type(field_type), intent(inout) :: adv_field, wind + type(field_type), intent(in) :: ls_adv_field, ls_wind + type(field_type), intent(inout) :: rhs + real(kind=r_def), intent(in) :: dt + integer(kind=i_def), intent(in) :: direction + type(transport_metadata_type), intent(in) :: transport_metadata + logical(kind=l_def), intent(in) :: final_rk_stage + type(adj_trans_lookup_cache_type), intent(in) :: adj_lookup_table_cache type(field_type) :: u_grad_f type(field_type) :: wind_v @@ -134,7 +137,8 @@ contains ! Horizontal update call atl_hori_wt_update_alg( u_grad_f, wind_h, ls_wind_h, ls_adv_field, transport_metadata ) - call adj_hori_wt_update_alg( u_grad_f, ls_wind_h, ls_wind_h, adv_field, transport_metadata ) + call adj_hori_wt_update_alg( u_grad_f, ls_wind_h, ls_wind_h, adv_field, transport_metadata, & + adj_lookup_table_cache ) call invoke( adj_split_w2_field_kernel_type(wind_h, wind_v, wind, & face_selector_ew, & @@ -143,7 +147,8 @@ contains case ( direction_h ) call atl_hori_wt_update_alg( u_grad_f, wind, ls_wind, ls_adv_field, transport_metadata ) - call adj_hori_wt_update_alg( u_grad_f, ls_wind, ls_wind, adv_field, transport_metadata ) + call adj_hori_wt_update_alg( u_grad_f, ls_wind, ls_wind, adv_field, transport_metadata, & + adj_lookup_table_cache ) case ( direction_v ) @@ -170,7 +175,6 @@ contains !> @param[in] transport_metadata Contains transport configuration options subroutine atl_hori_wt_update_alg(u_grad_f, wind, wind_dir, ls_field, transport_metadata) - use check_configuration_mod, only : get_required_stencil_depth use poly1d_reconstruction_kernel_mod, only : poly1d_reconstruction_kernel_type use poly2d_reconstruction_kernel_mod, only : poly2d_reconstruction_kernel_type use polyh_wtheta_koren_kernel_mod, only : polyh_wtheta_koren_kernel_type @@ -223,7 +227,7 @@ contains ! Copy field to a large halo version call ls_field_big_halo%initialise( ls_field%get_function_space(), & - halo_depth = get_required_stencil_depth() ) + halo_depth=mesh%get_halo_depth() ) call invoke( setval_X( ls_field_big_halo, ls_field ) ) ! Compute reconstruction on a Wtheta multidata field diff --git a/science/adjoint/source/kernel/inter_function_space/adj_sci_convert_hdiv_field_kernel_mod.F90 b/science/adjoint/source/kernel/inter_function_space/adj_sci_convert_hdiv_field_kernel_mod.F90 index 86f1ffce1..190108550 100644 --- a/science/adjoint/source/kernel/inter_function_space/adj_sci_convert_hdiv_field_kernel_mod.F90 +++ b/science/adjoint/source/kernel/inter_function_space/adj_sci_convert_hdiv_field_kernel_mod.F90 @@ -17,6 +17,10 @@ module adj_sci_convert_hdiv_field_kernel_mod CELL_COLUMN, GH_EVALUATOR use constants_mod, only : i_def, r_def +use base_mesh_config_mod, only: geometry, topology +use finite_element_config_mod, only: coord_system +use planet_config_mod, only: scaled_radius + !> NOTE: Kernel requires PSyKAl lite code to invoke. Kernel metadata commented out. !> Please see PSyclone issue #2798 for further information. implicit none @@ -107,6 +111,7 @@ subroutine adj_convert_hdiv_field_code(nlayers, & map_pid) use sci_coordinate_jacobian_mod, only : coordinate_jacobian + implicit none ! Arguments @@ -154,8 +159,10 @@ subroutine adj_convert_hdiv_field_code(nlayers, & chi3_e(df) = chi3(map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, ndf1, chi1_e(:), chi2_e(:), chi3_e(:), & - ipanel, basis_chi(:,:,:), diff_basis_chi(:,:,:), jacobian(:,:,:), dj(:)) + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, ndf1, chi1_e(:), chi2_e(:), chi3_e(:), & + ipanel, basis_chi(:,:,:), diff_basis_chi(:,:,:), & + jacobian(:,:,:), dj(:)) do df = ndf1, 1, -1 vector_out(3) = vector_out(3) + physical_field3(map1(df) + k) diff --git a/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 new file mode 100644 index 000000000..797685522 --- /dev/null +++ b/science/adjoint/source/kernel/linear_physics/atl_bl_inc_kernel_mod.F90 @@ -0,0 +1,177 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief (Adjoint of) computes u_inc, the change in TLM velocity due to TLM boundary layer processes. +module atl_bl_inc_kernel_mod + + use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, & + GH_REAL, CELL_COLUMN, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + use reference_element_mod, only : N + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + + type, public, extends(kernel_type) :: atl_bl_inc_kernel_type + private + type(arg_type) :: meta_args(7) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! u_inc + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! u + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Auv + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Buv_inv + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ew + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ew + arg_type(GH_SCALAR, GH_INTEGER, GH_READ) & ! Blevs_m + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: atl_bl_inc_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: atl_bl_inc_code + +contains + +!> @brief (Adjoint of) computes u_inc, the change in TLM velocity due to TLM boundary layer processes. +!> @details The algorithm uses coefficients Auv and Buv_inv computed in tl_compute_aubu_kernel_mod. +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] u_inc Change in TLM velocity due to TLM boundary layer processes +!! @param[in] u TLM velocity +!! @param[in] nlayers Number of layers +!! @param[in] Auv Coefficient for TLM boundary layer +!! @param[in] Buv_inv Inverse of coefficient for TLM boundary layer +!! @param[in] face_selector_ew 2D field indicating which W/E faces to loop over in this column +!! @param[in] face_selector_ns 2D field indicating which N/S faces to loop over in this column +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] ndf_w2 Number of degrees of freedom per cell for w2 space +!! @param[in] undf_w2 Number of unique degrees of freedom for w2 space +!! @param[in] map_w2 Dofmap for the cell at the base of the column for w2 +!! @param[in] ndf_w3_2d Number of DoFs for 2D W3 per cell +!! @param[in] undf_w3_2d Number of DoFs for this partition for 2D W3 +!! @param[in] map_w3_2d Map for 2D W3 +subroutine atl_bl_inc_code( nlayers, & + u_inc, & + u, & + Auv, & + Buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3_2d, undf_w3_2d, map_w3_2d ) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w2 + real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc + real(kind=r_def), dimension(undf_w2), intent(inout) :: u + integer(kind=i_def), intent(in) :: ndf_w2 + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + real(kind=r_def), dimension(undf_w2), intent(in) :: auv + real(kind=r_def), dimension(undf_w2), intent(in) :: buv_inv + integer(kind=i_def), intent(in) :: ndf_w3_2d + integer(kind=i_def), intent(in) :: undf_w3_2d + integer(kind=i_def), dimension(ndf_w3_2d), intent(in) :: map_w3_2d + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ew + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ns + integer(kind=i_def), intent(in) :: blevs_m + + ! Internal variables + integer(kind=i_def) :: df + integer(kind=i_def) :: k + integer(kind=i_def) :: j + real(kind=r_def), dimension(blevs_m) :: a0 ! Coefficient + real(kind=r_def), dimension(blevs_m) :: a1 ! Coefficient + real(kind=r_def), dimension(blevs_m) :: a2 ! Coefficient + real(kind=r_def), dimension(blevs_m) :: u_rhs ! Local perturbation velocity variable + real(kind=r_def), dimension(blevs_m) :: u_out ! Local perturbation velocity variable + real(kind=r_def), dimension(blevs_m) :: factor_u + + do j = face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)), 1, -1 + + df = j + if (j == 3 .and. face_selector_ns(map_w3_2d(1)) == 2 .and. face_selector_ew(map_w3_2d(1)) == 1) df = n + + u_out = 0.0_r_def + + ! Set up coeffs a0, a1, a2, u_rhs + a0(1) = 1.0_r_def + (Auv(map_w2(df) + 1) + Auv(map_w2(df) + 0)) / Buv_inv(map_w2(df) + 1) + a1(1) = -Auv(map_w2(df) + 1) / Buv_inv(map_w2(df) + 1) + a2(1) = 0.0_r_def + + do k = 2, BLevs_m - 1 + a0(k) = 1.0_r_def + (Auv(map_w2(df) + k) + Auv(map_w2(df) + k - 1)) / Buv_inv(map_w2(df) + k) + a1(k) = -Auv(map_w2(df) + k) / Buv_inv(map_w2(df) + k) + a2(k) = -Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + end do + + a0(BLevs_m) = 1.0_r_def + Auv(map_w2(df) + BLevs_m - 1) / Buv_inv(map_w2(df) + BLevs_m) + a1(BLevs_m) = 0.0_r_def + a2(BLevs_m) = -Auv(map_w2(df) + BLevs_m - 1) / Buv_inv(map_w2(df) + BLevs_m) + + a0(1) = 1.0_r_def / a0(1) + + do k = 2, BLevs_m + factor_u(k) = a2(k) * a0(k - 1) + a0(k) = 1.0_r_def / (a0(k) - factor_u(k) * a1(k - 1)) + end do + + ! (Adjoint of) solve for u_inc and transform to upper triangular form + do k = 1, blevs_m - 1 + u_out(k) = u_out(k) + u_inc(map_w2(df) + k - 1) + u_inc(map_w2(df) + k - 1) = 0.0_r_def + + u_out(k + 1) = u_out(k + 1) + (-a0(k) * a1(k) * u_out(k)) + u_rhs(k) = a0(k) * u_out(k) + end do + + u_out(blevs_m) = u_out(blevs_m) + u_inc(map_w2(df) + blevs_m - 1) + u_inc(map_w2(df) + blevs_m - 1) = 0.0_r_def + + u_rhs(blevs_m) = a0(blevs_m) * u_out(blevs_m) + + do k = blevs_m, 2, -1 + u_rhs(k - 1) = u_rhs(k - 1) + (-factor_u(k) * u_rhs(k)) + end do + + u(blevs_m + map_w2(df) - 2) = u(blevs_m + map_w2(df) - 2) + & + auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) + u(blevs_m + map_w2(df) - 1) = u(blevs_m + map_w2(df) - 1) - & + auv(blevs_m + map_w2(df) - 1) * u_rhs(blevs_m) / buv_inv(blevs_m + map_w2(df)) + + do k = blevs_m - 1, 2, -1 + u(k + map_w2(df)) = u(k + map_w2(df)) + auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df)) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 2) = u(k + map_w2(df) - 2) + auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) + u(k + map_w2(df) - 1) = u(k + map_w2(df) - 1) - auv(k + map_w2(df) - 1) * u_rhs(k) / buv_inv(k + map_w2(df)) + end do + + u(map_w2(df) + 1) = u(map_w2(df) + 1) + auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df) + 1) * u_rhs(1) / buv_inv(map_w2(df) + 1) + u(map_w2(df)) = u(map_w2(df)) - auv(map_w2(df)) * u_rhs(1) / buv_inv(map_w2(df) + 1) + + end do + +end subroutine atl_bl_inc_code + +end module atl_bl_inc_kernel_mod diff --git a/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 b/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 index f0fb299e4..e330c4bad 100644 --- a/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 +++ b/science/adjoint/source/kernel/transport/mol/atl_poly1d_vert_w3_reconstruction_kernel_mod.F90 @@ -129,34 +129,34 @@ subroutine atl_poly1d_vert_w3_reconstruction_code( nlayers, & real(kind=r_def) :: new_tracer real(kind=r_def) :: ls_new_tracer - new_tracer = 0.0_r_def vertical_order = MIN(global_order, nlayers - 1) ij = map_w3(1) if (logspace) then do f = 1, 0, -1 do k = nlayers - 1, 0, -1 ls_new_tracer = 1.0_r_def - new_tracer = new_tracer + ls_new_tracer * reconstruction(map_md(1) + f * nlayers + k) + do p = 1, vertical_order + 1 + ik = f * global_order + f + k * ndata + p + map_c(1) - 1 + ls_new_tracer = ls_new_tracer * MAX(eps, ABS(ls_tracer(ij + stencil(p,k,f)))) ** coeff(ik) + end do + new_tracer = ls_new_tracer * reconstruction(map_md(1) + f * nlayers + k) reconstruction(map_md(1) + f * nlayers + k) = 0.0_r_def do p = vertical_order + 1, 1, -1 ik = f * global_order + f + k * ndata + p + map_c(1) - 1 - ls_new_tracer = ls_new_tracer * MAX(eps, ABS(ls_tracer(ij + stencil(p,k,f)))) ** coeff(ik) tracer(ij + stencil(p,k,f)) = tracer(ij + stencil(p,k,f)) + coeff(ik) * new_tracer / SIGN(MAX(eps, ls_tracer(ij + & &stencil(p,k,f))), ls_tracer(ij + stencil(p,k,f))) enddo - new_tracer = 0.0_r_def enddo enddo else do f = 1, 0, -1 do k = nlayers - 1, 0, -1 - new_tracer = new_tracer + reconstruction(map_md(1) + f * nlayers + k) + new_tracer = reconstruction(map_md(1) + f * nlayers + k) reconstruction(map_md(1) + f * nlayers + k) = 0.0_r_def do p = vertical_order + 1, 1, -1 ik = f * global_order + f + k * ndata + p + map_c(1) - 1 tracer(ij + stencil(p,k,f)) = tracer(ij + stencil(p,k,f)) + coeff(ik) * new_tracer enddo - new_tracer = 0.0_r_def enddo enddo end if diff --git a/science/adjoint/source/kernel/transport/mol/atl_poly_adv_update_kernel_mod.F90 b/science/adjoint/source/kernel/transport/mol/atl_poly_adv_update_kernel_mod.F90 index 972aa52d6..e1a89201b 100644 --- a/science/adjoint/source/kernel/transport/mol/atl_poly_adv_update_kernel_mod.F90 +++ b/science/adjoint/source/kernel/transport/mol/atl_poly_adv_update_kernel_mod.F90 @@ -152,10 +152,7 @@ subroutine atl_poly_adv_update_code( nlayers, & real(kind=r_tran) :: ls_dtdy - uv = 0.0_r_tran - v_dot_n(:) = 1.0_r_tran - v_dot_n(1) = -1.0_r_tran - v_dot_n(nfaces) = -1.0_r_tran + v_dot_n = (/ -1.0_r_tran, 1.0_r_tran, 1.0_r_tran, -1.0_r_tran /) opposite(:) = -1 missing_neighbour(:) = .false. @@ -186,9 +183,7 @@ subroutine atl_poly_adv_update_code( nlayers, & uv_dir(1,k) = 0.25_r_tran * wind_dir(k + map_w2(1) - 1) + 0.25_r_tran * wind_dir(k + map_w2(3) - 1) uv_dir(2,k) = 0.25_r_tran * wind_dir(k + map_w2(2) - 1) + 0.25_r_tran * wind_dir(k + map_w2(4) - 1) - direction_dofs(:) = 1 - direction_dofs(2) = 2 - direction_dofs(4) = 2 + direction_dofs(:) = (/ 1, 2, 1, 2 /) do df = 1, nfaces, 1 do k = 0, nlayers, 1 @@ -206,39 +201,33 @@ subroutine atl_poly_adv_update_code( nlayers, & do k = nlayers, 0, -1 ls_dtdx = ls_tracer(e,k) - ls_tracer(w,k) ls_dtdy = ls_tracer(n,k) - ls_tracer(s,k) - uv(1,k) = uv(1,k) + ls_dtdx * advective(map_wt(1) + k) - uv(2,k) = uv(2,k) - ls_dtdy * advective(map_wt(1) + k) + uv(1,k) = ls_dtdx * advective(map_wt(1) + k) + uv(2,k) = -ls_dtdy * advective(map_wt(1) + k) advective(map_wt(1) + k) = 0.0_r_tran enddo k = nlayers wind(k + map_w2(2) - 1) = wind(k + map_w2(2) - 1) + 0.25_r_tran * uv(2,k) wind(k + map_w2(4) - 1) = wind(k + map_w2(4) - 1) + 0.25_r_tran * uv(2,k) - uv(2,k) = 0.0_r_tran wind(k + map_w2(1) - 1) = wind(k + map_w2(1) - 1) + 0.25_r_tran * uv(1,k) wind(k + map_w2(3) - 1) = wind(k + map_w2(3) - 1) + 0.25_r_tran * uv(1,k) - uv(1,k) = 0.0_r_tran do k = nlayers - 1, 1, -1 wind(k + map_w2(2)) = wind(k + map_w2(2)) + 0.25_r_tran * uv(2,k) wind(k + map_w2(4)) = wind(k + map_w2(4)) + 0.25_r_tran * uv(2,k) wind(k + map_w2(2) - 1) = wind(k + map_w2(2) - 1) + 0.25_r_tran * uv(2,k) wind(k + map_w2(4) - 1) = wind(k + map_w2(4) - 1) + 0.25_r_tran * uv(2,k) - uv(2,k) = 0.0_r_tran wind(k + map_w2(1)) = wind(k + map_w2(1)) + 0.25_r_tran * uv(1,k) wind(k + map_w2(3)) = wind(k + map_w2(3)) + 0.25_r_tran * uv(1,k) wind(k + map_w2(1) - 1) = wind(k + map_w2(1) - 1) + 0.25_r_tran * uv(1,k) wind(k + map_w2(3) - 1) = wind(k + map_w2(3) - 1) + 0.25_r_tran * uv(1,k) - uv(1,k) = 0.0_r_tran enddo k = 0 wind(map_w2(2)) = wind(map_w2(2)) + 0.25_r_tran * uv(2,k) wind(map_w2(4)) = wind(map_w2(4)) + 0.25_r_tran * uv(2,k) - uv(2,k) = 0.0_r_tran wind(map_w2(1)) = wind(map_w2(1)) + 0.25_r_tran * uv(1,k) wind(map_w2(3)) = wind(map_w2(3)) + 0.25_r_tran * uv(1,k) - uv(1,k) = 0.0_r_tran end subroutine atl_poly_adv_update_code diff --git a/science/adjoint/source/kernel/transport/mol/atl_w3h_advective_update_kernel_mod.F90 b/science/adjoint/source/kernel/transport/mol/atl_w3h_advective_update_kernel_mod.F90 index fca1ec80a..021af5e9d 100644 --- a/science/adjoint/source/kernel/transport/mol/atl_w3h_advective_update_kernel_mod.F90 +++ b/science/adjoint/source/kernel/transport/mol/atl_w3h_advective_update_kernel_mod.F90 @@ -165,8 +165,6 @@ subroutine atl_w3h_advective_update_code( cell, & ! so if u.n > 0 then we set the field to be the value on this edge from this cell ! and if u.n < 0 then we set the field to be the value on this edge from a ! neighbouring cell - u = 0.0_r_def - v = 0.0_r_def do k = nlayers - 1, 0, -1 ! u * dt/dx @@ -218,16 +216,14 @@ subroutine atl_w3h_advective_update_code( cell, & dtdy = t_N - t_S ik = 1 + k + (cell-1)*nlayers - u = u + m3_inv(ik,1,1) * dtdx * advective_increment(map_w3(1)+k) - v = v + m3_inv(ik,1,1) * dtdy * advective_increment(map_w3(1)+k) + u = m3_inv(ik,1,1) * dtdx * advective_increment(map_w3(1)+k) + v = m3_inv(ik,1,1) * dtdy * advective_increment(map_w3(1)+k) wind(map_w2(2) + k) = wind(map_w2(2) + k) - 0.5_r_def * v wind(map_w2(4) + k) = wind(map_w2(4) + k) - 0.5_r_def * v - v = 0.0_r_def wind(map_w2(1) + k) = wind(map_w2(1) + k) + 0.5_r_def * u wind(map_w2(3) + k) = wind(map_w2(3) + k) + 0.5_r_def * u - u = 0.0_r_def end do end subroutine atl_w3h_advective_update_code diff --git a/science/gungho/integration-test/cma_test/cma_test.f90 b/science/gungho/integration-test/cma_test/cma_test.f90 index 2797865da..50ae0f9a4 100644 --- a/science/gungho/integration-test/cma_test/cma_test.f90 +++ b/science/gungho/integration-test/cma_test/cma_test.f90 @@ -19,7 +19,6 @@ program cma_test use, intrinsic :: iso_fortran_env, only : real64 - use check_configuration_mod, only : get_required_stencil_depth use cma_test_algorithm_mod, only : cma_test_init, & test_cma_apply_mass_p, & test_cma_apply_mass_v, & @@ -29,7 +28,7 @@ program cma_test test_cma_add, & test_cma_apply_inv, & test_cma_diag_DhMDhT - use constants_mod, only : i_def, r_def, i_def, l_def, & + use constants_mod, only : i_def, r_def, i_def, l_def, imdi, & r_solver, pi, str_def use derived_config_mod, only : set_derived_config use extrusion_mod, only : extrusion_type, & @@ -130,7 +129,7 @@ program cma_test type(namelist_type), pointer :: base_mesh_nml type(namelist_type), pointer :: planet_nml - integer(i_def) :: stencil_depth + integer(i_def) :: stencil_depth(1) character(str_def) :: file_prefix character(str_def) :: prime_mesh_name real(r_def) :: radius @@ -289,7 +288,7 @@ program cma_test domain_height, & scaled_radius ) ) - stencil_depth = get_required_stencil_depth() + stencil_depth = 2 check_partitions = .false. call init_mesh( configuration, & local_rank, total_ranks, & @@ -307,7 +306,8 @@ program cma_test alt_name=twod_names ) call assign_mesh_maps(twod_names) - call init_chi_transforms(mesh_collection) + call init_chi_transforms(geometry_spherical, imdi, & + mesh_collection=mesh_collection) ! Work out grid spacing, which should be of order 1 mesh => mesh_collection%get_mesh(prime_mesh_name) diff --git a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf index 15f3d9684..4380951b7 100644 --- a/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf +++ b/science/gungho/rose-meta/lfric-gungho/HEAD/rose-meta.conf @@ -4705,7 +4705,7 @@ ns=namelist/Science [namelist:physics=bl_segment] compulsory=true description=Over-rides bl_segment_size in physics -fail-if=this <= 0 ; +fail-if=this < 0 ; help=Boundary layer segment size. = =Setting bl_segment=0 will trigger the default behaviour @@ -4731,11 +4731,22 @@ description=Configure OMP segment lengths in physics schemes help=This will allow segmentation of physics loops and thereform OMP performance to be tuned !kind=default trigger=namelist:physics=bl_segment: .true. ; + =namelist:physics=conv_gr_segment: .true. ; =namelist:physics=gw_segment: .true. ; =namelist:physics=ls_ppn_segment: .true. ; =namelist:physics=ussp_segment: .true. ; type=logical +[namelist:physics=conv_gr_segment] +compulsory=true +description=Number of segments to be processed in Gregory-Rowntree convection +help=This determines the segment size to be processed. + = This sub-segment will be processed in a loop. + = A sensible default seems to be 16. +!kind=default +range=1:9999999 +type=integer + [namelist:physics=convection_placement] compulsory=true description=Convection placement @@ -4772,7 +4783,7 @@ values='fast','slow' [namelist:physics=gw_segment] compulsory=true description=Over-rides gw_seg_size in um physics -fail-if=this <= 0 ; +fail-if=this < 0 ; help=Break segments gravity wave. = =Setting gw_segment=0 will trigger the default behaviour @@ -5328,6 +5339,7 @@ help=Currently JULES is the only surface scheme available for use sort-key=Panel-A10 trigger=namelist:surface: this == "'jules'" ; =namelist:jules_hydrology: this == "'jules'" ; + =namelist:jules_model_environment_lfric: this == "'jules'" ; =namelist:jules_nvegparm: this == "'jules'" ; =namelist:jules_pftparm: this == "'jules'" ; =namelist:jules_radiation: this == "'jules'" ; @@ -5798,9 +5810,22 @@ sort-key=Panel-A25 trigger= type=real +[namelist:transport=adjust_tracer_equation] +compulsory=true +description=Adjusts the equation form of conservative tracer groups to + =advective form if Watkins algorithm is unable to fix large + =Lipschitz numbers for consistent transport. This will break + =tracer convservation for any time steps this is needed. +fail-if= +help=Must be used with FFSL and SWIFT splittings +!kind=default +sort-key=Panel-A31 +trigger= +type=logical + [namelist:transport=adjust_vhv_wind] compulsory=true -description=Adujsts the first and final vertical winds in a Strang VHV splitting +description=Adjusts the first and final vertical winds in a Strang VHV splitting =to avoid breaking any Lipschitz condition. fail-if= help=Must be used with 3D FFSL and SWIFT splittings diff --git a/science/gungho/rose-meta/lfric-gungho/version30_31.py b/science/gungho/rose-meta/lfric-gungho/version30_31.py new file mode 100644 index 000000000..09b9ecc07 --- /dev/null +++ b/science/gungho/rose-meta/lfric-gungho/version30_31.py @@ -0,0 +1,193 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + return config, self.reports diff --git a/science/gungho/rose-meta/lfric-gungho/versions.py b/science/gungho/rose-meta/lfric-gungho/versions.py index 152c043d0..01798ad2b 100644 --- a/science/gungho/rose-meta/lfric-gungho/versions.py +++ b/science/gungho/rose-meta/lfric-gungho/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/science/gungho/rose-meta/lfric-gungho/vn3.1/rose-meta.conf b/science/gungho/rose-meta/lfric-gungho/vn3.1/rose-meta.conf new file mode 100644 index 000000000..26b0b447a --- /dev/null +++ b/science/gungho/rose-meta/lfric-gungho/vn3.1/rose-meta.conf @@ -0,0 +1,6856 @@ +import=lfric-driver/vn3.1 + =jules-lsm/vn3.1 + =socrates-radiation/vn3.1 + =um-aerosol/vn3.1 + =um-boundary_layer/vn3.1 + =um-chemistry/vn3.1 + =um-cloud/vn3.1 + =um-convection/vn3.1 + =um-iau/vn3.1 + =um-microphysics/vn3.1 + =um-orographic_drag/vn3.1 + =um-spectral_gwd/vn3.1 + =um-stochastic_physics/vn3.1 + +[!0.1 Namelist Maintainers] +#============================================================ +# Initial developers available to maintain namelist metadata +#============================================================ +# base_mesh | Ricky Wong +# boundaries | Christine Johnson +# checks | Ben Shipway +# damping_layer | Ben Shipway +# departure_points | James Kent, Stephen Pring +# energy_correction | Chris Smith +# external_forcing | Ian Boutle +# extrusion | Thomas Melvin, Iva Kavcic +# finite_element | Thomas Melvin +# formulation | Thomas Melvin +# helmholtz_solver | Thomas Melvin +# iau_addinf_io | Warren Tennant, Samantha Pullen +# iau_ainc_io | Warren Tennant, Samantha Pullen +# iau_bcorr_io | Warren Tennant, Samantha Pullen +# idealised | Stephen Pring +# initial_density | Stephen Pring +# initial_pressure | Chris Smith +# initial_temperature | Ben Shipway +# initial_vapour | Chris Smith +# initial_wind | Ben Shipway +# io | Samantha Adams +# jules-lfric | Maggie Hendry +# jules-hydrology | Maggie Hendry +# jules-nvegparm | Maggie Hendry +# jules-pftparm | Maggie Hendry +# jules-radiation | Maggie Hendry +# jules-sea-seaice | Maggie Hendry +# jules-snow | Maggie Hendry +# jules-soil | Maggie Hendry +# jules-surface | Maggie Hendry +# jules-surface-types | Maggie Hendry +# jules-urban | Maggie Hendry +# jules-vegetation | Maggie Hendry +# mixed_solver | Thomas Melvin +# mixing | Thomas Melvin, Kirsty Hanley +# multigrid | Ricky Wong +# multires_coupling | Thomas Bendall, Alex Brown +# esm_couple | Richard Hill +# orbit | James Manners +# orography | Iva Kavcic +# orography_agnesi_cartesian | Iva Kavcic +# orography_agnesi_spherical | Iva Kavcic +# orography_dcmip200_spherical | Iva Kavcic +# orography_schar_cartesian | Iva Kavcic +# orography_schar_spherical | Iva Kavcic +# partitioning | Mike Hobson +# physics | Ben Shipway +# planet | Thomas Melvin +# section_choice | Ricky Wong +# socrates-radiation | James Manners +# solver | Thomas Melvin +# star | James Manners +# submission | Ricky Wong +# time | Matthew Hambley +# timestepping | Thomas Melvin +# transport | Stephen Pring, Thomas Melvin +# um-aerosol | Alan J Hewitt +# um-boundary_layer | Ian Boutle +# um-chemistry | Mohit Dalvi +# um-cloud | Kwinten Van Weverberg +# um-convection | Ian Boutle +# um-iau | Warren Tennant, Samantha Pullen +# um-microphysics | Jonathan Wilkinson +# um-orographic_drag | Annelize van Niekerk +# um-spectral_gwd | Annelize van Niekerk +# um-stochastic_physics | Claudio Sanchez, Warren Tennant +!= + +#============================================================================== +# SYSTEM SETTINGS +#============================================================================== +[Submission] +ns=namelist/Job/Submission +sort-key=Section-001 + +#============================================================================== +# ENVIRONMENT VARIABLES AVAILABLE TO ROSE TASK +#============================================================================== +[env] +compulsory=true + +[env=ENSEMBLE_MEMBER] +compulsory=true +description=Ensemble member number +sort-key=Panel-A06 +type=integer + +[env=EXEC_NAME] +compulsory=true +description=Program executable name +sort-key=Panel-A01 +type=raw + +[env=OMP_NUM_THREADS] +compulsory=true +description=Number of threads for OpenMP +fail-if=this < 1 ; +range=1: +sort-key=Panel-A03 +type=integer + +[env=TOTAL_RANKS] +compulsory=true +description=Number of process ranks for a parallel run job +fail-if=this < 1 ; +range=1: +sort-key=Panel-A02 +type=integer + +[env=XIOS_SERVER_MODE] +compulsory=true +description=Run with XIOS in server mode +sort-key=Panel-A04 +type=python_boolean + +[env=XIOS_SERVER_RANKS] +compulsory=true +description=XIOS server process ranks +fail-if=this < 1 ; +range=1: +sort-key=Panel-A05 +type=integer + +#============================================================================== +# INITIAL CONDITIONS +#============================================================================== +[initial_conditions] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Job/Initial conditions +sort-key=Section-A04 + +[io_checkpoint_restart] +compulsory=false +description=Settings for writing and restarting the model from checkpoints. +ns=namelist/Job/IO/Checkpointing & Restart +sort-key=Section-A02 + +[io_diagnostics] +compulsory=false +description=Atmospheric model diagnostic output settings +ns=namelist/Job/IO/Diagnostics +sort-key=Section-A03 + +[io_dump] +compulsory=false +description=Atmospheric model dump settings +ns=namelist/Job/IO/Dumping +sort-key=Section-A03 + +[io_field_init] +compulsory=false +description=Settings that control how a field is initialised +ns=namelist/Job/IO/Field Initialisation +sort-key=Section-A03 + +[io_system] +compulsory=false +description=System related I/O for statistics and debugging +ns=namelist/Job/IO/System +sort-key=Section-A01 + +[jinja:suite.rc=threads] +compulsory=true +description=???? +help=??? +ns=namelist/Job/Submission +sort-key=Panel-A03 + +[jinja:suite.rc=wallclock] +compulsory=true +description=???? +help=??? +ns=namelist/Job/Submission +sort-key=Panel-A02 + +[jinja:suite.rc=xios_nodes] +compulsory=true +description=???? +help=??? +ns=namelist/Job/Submission +sort-key=Panel-A04 + +#============================================================================== +# JOB RUN +#============================================================================== +[job details] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Job +sort-key=Section-A02 +title=Job + +[job details=end_date] +compulsory=false +type=integer + +[job details=nprocessors] +compulsory=false + +[job details=nsubs] +compulsory=false +range=1: +type=integer + +[job details=start_date] +compulsory=false +type=integer + +#============================================================================== +# MODEL SETUP +#============================================================================== +[model setup] +compulsory=false +description=?????? +help=This section is for configuration of the model geometry. +ns=namelist/Model +sort-key=Section-A01 +title=Model + +#============================================================================== +# OROGRAPHY TRIGGERS FROM GEOMETRY +#============================================================================== +[namelist:base_mesh=geometry] +trigger=namelist:orography_agnesi_cartesian: this == "'planar'" ; + =namelist:orography_bell_cartesian: this == "'planar'" ; + =namelist:orography_schar_cartesian: this == "'planar'" ; + =namelist:base_mesh=fplane: this == "'planar'" ; + =namelist:base_mesh=f_lat_deg: this == "'planar'" ; + =namelist:orography_agnesi_spherical: this == "'spherical'" ; + =namelist:orography_bell_spherical: this == "'spherical'" ; + =namelist:orography_schar_spherical: this == "'spherical'" ; + =namelist:orography_dcmip200_spherical: this == "'spherical'" ; + +#============================================================================== +# LIMITED AREA TRIGGERS FROM BASE MESH TOPOLOGY +#============================================================================== +[namelist:base_mesh=topology] +trigger=namelist:boundaries=transport_boundary_depth: this == "'non_periodic'" ; + +#============================================================================== +# LIMITED AREA +#============================================================================== +[namelist:boundaries] +compulsory=true +description=Lateral boundary conditions for running limited-area, regional + =models. +help=Specify whether to use lateral boundary conditions and the physical + =location of the boundaries. +ns=namelist/Science/Dynamics/Boundaries +sort-key=Section-A00 + +[namelist:boundaries=blend_frequency] +compulsory=true +description=Frequency of calls to blending +!enumeration=true +help=Options for when the blending is done within the semi-implicit + =timestep: + = 'inner': The blending is done at the end of each inner iteration + = 'outer': The blending is done at the end of the final inner + = iteration within each outer iteration + = 'final': The blending is done at the end of the final inner + = iteration within the final outer iteration +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A08 +value-titles=Inner, Outer, Final +values='inner', 'outer', 'final' + +[namelist:boundaries=blending_weights] +compulsory=true +description=Rim weights from outermost first inwards +fail-if=this <= 0.0 ; +help=The blending zone is the region around the edge (rim) of the + =model domain where data will undergo weighted relaxation back to + =the values in the LBC data fields. + = + =Blending weights are applied at each layer of cells from the domain + =edge radiating inwards using: + = + = Field_updated = Weighting*Field_LBC_data + (1 - Weighting)*Field_model_data + = + =Blending weights should be specified for each layer from 1.0, decreasing + =monotonically. + = + =Note: + = * The number of blending weights must be <= number of available rim layers + = in the LBC data fields. + = * Blending weight values should be > 0.0 + = * The outer weights may need to be padded with values of 1 depending + = on the choices made in the science configuration. + = +!kind=default +length=: +ns=namelist/Science/Dynamics/Boundaries +range=this > 0.0 and this <= 1.0 +sort-key=Panel-A03 +type=real + +[namelist:boundaries=blending_weights_w2v] +compulsory=true +description=Rim weights from outermost first inwards, for the W2V space. +fail-if=this <= 0.0 ; +help=Identical to the blending_weights, but only applied to the W2V space + =i.e. the Top and bottom dofs for the wind/momentum space. + =This controls the amount of damping of the vertical wind in the blending + =zone. +!kind=default +length=: +ns=namelist/Science/Dynamics/Boundaries +range=this > 0.0 and this <= 1.0 +sort-key=Panel-A03 +type=real + +[namelist:boundaries=boundary_e] +compulsory=true +description=The number of cells to the Eastern linear solver boundary. +fail-if=this <0 ; +help=Specify the position of the Eastern lateral boundary + =for the linear solver. This is the number of cells from + =the Eastern edge of the mesh (or panel if using a cubed-sphere). +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=0: +sort-key=Panel-A05 +type=integer + +[namelist:boundaries=boundary_n] +compulsory=true +description=The number of cells to the Northern linear solver boundary. +fail-if=this <0 ; +help=Specify the position of the Northern lateral boundary + =for the linear solver. This is the number of cells from + =the Northern edge of the mesh (or panel if using a cubed-sphere). +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=0: +sort-key=Panel-A03 +type=integer + +[namelist:boundaries=boundary_s] +compulsory=true +description=The number of cells to the Southern linear solver boundary. +fail-if=this <0 ; +help=Specify the position of the Southern lateral boundary + =for the linear solver. This is the number of cells from + =the Southern edge of the mesh (or panel if using a cubed-sphere). +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=0: +sort-key=Panel-A04 +type=integer + +[namelist:boundaries=boundary_w] +compulsory=true +description=The number of cells to the Western linear solver boundary. +fail-if=this <0 ; +help=Specify the position of the Western lateral boundary + =for the linear solver. This is the number of cells from + =the Western edge of the mesh (or panel if using a cubed-sphere). +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=0: +sort-key=Panel-A06 +type=integer + +[namelist:boundaries=edge_cells_ew] +compulsory=true +description=Total number of mesh cells in East-West direction. +fail-if=this <1 ; +help=Specify the total number of cells along the E-W edge of the planar domain + =or the total number of cells along the edge of a cubed-sphere panel. +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=1: +sort-key=Panel-A02 +type=integer + +[namelist:boundaries=edge_cells_ns] +compulsory=true +description=Total number of mesh cells in North-South direction. +fail-if=this <1 ; +help=Specify the total number of cells along the N-S edge of the planar domain + =or the total number of cells along the edge of a cubed-sphere panel. +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=1: +sort-key=Panel-A01 +type=integer + +[namelist:boundaries=inner_width_ew] +compulsory=true +description=Number of cells to be overwritten inside E/W solver boundary. +fail-if=this > namelist:boundaries=rim_width_ew - namelist:boundaries=outer_width_ew +help=Specify the number of cells on the INTERIOR side of + =the solver boundary (boundary_e or boundary_w) to be + =overwritten by the driving model data. + = + = Mesh edge Solver boundary + = |<------boundary_w...----->| + = |<----***------------rim_width_ew---------------------***----->| + = |<--outer_width_ew--->|<-.inner_width_ew.->|.....blend.........| +!kind=default +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A10 +type=integer + +[namelist:boundaries=inner_width_ns] +compulsory=true +description=Number of cells to be overwritten inside N/S solver boundary. +fail-if=this > namelist:boundaries=rim_width_ns - namelist:boundaries=outer_width_ns +help=Specify the number of cells on the INTERIOR side of + =the solver boundary (boundary_n or boundary_s) to be + =overwritten by the driving model data. + = + = Mesh edge Solver boundary + = |<------boundary_n...----->| + = |<----***------------rim_width_ns---------------------***----->| + = |<--outer_width_ns--->|<-.inner_width_ns.->|.....blend.........| + = +!kind=default +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A09 +type=integer + +[namelist:boundaries=lbc_eos_height] +compulsory=true +description=Exner initialisation height for LBCs [%]. +help=The value is an integer percentage of the atmospheric depth before any application of orography. + =It is used to determine the atmospheric layer/level at which to begin Exner profile initialisation + =for the lateral boundary conditions. The Equation of State (EoS) is satisfied at the resulting layer + =where Exner initialisation begins. + = + =To initialise an Exner vertical profile, the Equation of state (EoS) is first used + =to calculate Exner on a single vertical layer L using density and temperature. + =This vertical layer L is the nearest layer to (lbc_eos_height/100)*total_height. + =Then hydrostatic balance is used to integrate from this layer to the top of the atmosphere, + =and similarly to the bottom of the atmosphere. + = + =If lbc_eos_height=0, the initial layer is 1 so the EoS is solved for the bottom layer + =and then hydrostatic balance is used to integrate upwards to the top of the model. + =If lbc_eos_height=100, the initial layer is number_of_layers, so the EoS is solved for the + =top layer, and then hydrostatic balance is used to integrate downwards to the bottom of the model. + = + =It is also possible to use any value between 0 and 100, so that hydrostatic balance is + =used to integrate both upwards and downwards. +range=0:100 +sort-key=Panel-A01 +type=integer + +[namelist:boundaries=lbc_method] +compulsory=true +description=LBC rim weights/mask generation method +!enumeration=true +help=Onion Layer + =---------------- + =Blending weights used to imply depth of + =rim region where weights are applied to + =LBC data. + = + =Coordinate based + =---------------- + =Physical coordinates used to determine + =locations and therefore weights and masks. + = +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A08 +trigger=namelist:boundaries=blending_weights: this == "'onion_layer'" ; + =namelist:boundaries=blending_weights_w2v: this == "'onion_layer'" ; + =namelist:boundaries=solver_boundary_depth: this == "'onion_layer'" ; + =namelist:boundaries=edge_cells_ns: this == "'coordinate_based'" ; + =namelist:boundaries=edge_cells_ew: this == "'coordinate_based'" ; + =namelist:boundaries=boundary_e: this == "'coordinate_based'" ; + =namelist:boundaries=boundary_w: this == "'coordinate_based'" ; + =namelist:boundaries=boundary_n: this == "'coordinate_based'" ; + =namelist:boundaries=boundary_s: this == "'coordinate_based'" ; + =namelist:boundaries=rim_width_ns: this == "'coordinate_based'" ; + =namelist:boundaries=rim_width_ew: this == "'coordinate_based'" ; +value-titles=Onion Layer, Coordinate based +values='onion_layer','coordinate_based' + +[namelist:boundaries=limited_area] +compulsory=true +description=Running in limited_area configuration. +help=Run as a limited area model and impose lateral boundary conditions + =(currently with zero flux boundary conditions). +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A00 +trigger=namelist:boundaries=normal_only: .true. ; + =namelist:boundaries=output_lbcs: .true. ; + =namelist:boundaries=lbc_method: .true. ; + =namelist:boundaries=transport_boundary_depth: .true. ; + =namelist:boundaries=blend_frequency: .true. ; + =namelist:boundaries=lbc_eos_height: .true. ; +type=logical + +[namelist:boundaries=normal_only] +compulsory=true +description=Use only W2 degrees of freedom (dofs) on the boundary for LBCs. +help=When '.true.' use the W2 dofs on the boundary (the normal + =component of the wind). When '.false.' use the W2 dofs on the + =boundary and 1 cell in (the normal and tangential components). +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A00 +type=logical + +[namelist:boundaries=outer_width_ew] +compulsory=true +description=Number of cells to be overwritten outside E/W solver boundary. +help=Specify the number of cells on the EXTERIOR side of + =the solver boundary (boundary_e or boundary_w) to be + =overwritten by the driving model data. This will often + =be the same value as boundary_e and boundary_w. + = + = Mesh edge Solver boundary + = |<------boundary_w...----->| + = |<----***------------rim_width_ew---------------------***----->| + = |<--outer_width_ew--->|<-.inner_width_ew.->|.....blend.........| + = +!kind=default +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A12 +type=integer + +[namelist:boundaries=outer_width_ns] +compulsory=true +description=Number of cells to be overwritten outside N/S solver boundary. +help=Specify the number of cells on the EXTERIOR side of + =the solver boundary (boundary_n or boundary_s) to be + =overwritten by the driving model data. This will often + =be the same value as boundary_n and boundary_s. + = + = Mesh edge Solver boundary + = |<------boundary_n...----->| + = |<----***------------rim_width_ns---------------------***----->| + = |<--outer_width_ns--->|<-.inner_width_ns.->|.....blend.........| + = +!kind=default +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A11 +type=integer + +[namelist:boundaries=output_lbcs] +compulsory=true +description=Output the lbcs in the diagnostics file +help= +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A00 +type=logical + +[namelist:boundaries=rim_width_ew] +compulsory=true +description=Total number of cells of the East-West LBC data. +help=a) If rim_width_ew>0 this is the number of cells (an integer) for the + = width of the lateral boundary condition (LBC) on both the East and West + = boundaries. + = The blending weight is 1 in outer_width_ew and inner_width_ew - where + = the data is overwritten with the driving model data. + = The blending weight then ramps down from 1 to 0 in the remaining cells + = in rim_width_ew - where the data is blended with the driving model data. + =b) If rim_width_ew=0 then the width of the lateral boundary condition + = data is zero - but a boundary condition is still enforced in the linear + = solver (for models with no advection). + =c) If rim_width_ew<0 then there is no boundary condition - on both the + = East and West boundaries. i.e. periodic boundary conditions are enforced + = instead. +!kind=default +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A08 +trigger=namelist:boundaries=inner_width_ew: this > 0 ; + =namelist:boundaries=outer_width_ew: this > 0 ; +type=integer + +[namelist:boundaries=rim_width_ns] +compulsory=true +description=Total number of cells of the North-South LBC data. +help=a) If rim_width_ns>0 this is the number of cells (an integer) for the + = width of the lateral boundary condition (LBC) on both the North and South + = boundaries. + = The blending weight is 1 in outer_width_ns and inner_width_ns- where + = the data is overwritten with the driving model data. + = The blending weight then ramps down from 1 to 0 in the remaining cells + = in rim_width_ns - where the data is blended with the driving model data. + =b) If rim_width_ns=0 then the width of the lateral boundary condition + = data is zero - but a boundary condition is still enforced in the linear + = solver (for models with no advection). + =c) If rim_width_ns<0 then there is no boundary condition - on both the + = North and South boundaries. i.e. periodic boundary conditions are + = enforced instead. +!kind=default +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A07 +trigger=namelist:boundaries=inner_width_ns: this > 0 ; + =namelist:boundaries=outer_width_ns: this > 0 ; +type=integer + +[namelist:boundaries=solver_boundary_depth] +compulsory=true +description=Depth to boundary of linear solver (in cells) +fail-if=this <0 ; +help=Specifies the location of the lateral edge boundary of the + =linear solver domain. The distance to the boundary is + =given as number cells inward from the mesh domain edge. +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=0: +sort-key=Panel-A05 +type=integer + +[namelist:boundaries=transport_boundary_depth] +compulsory=true +description=Depth to boundary of transport scheme (in cells). +fail-if=this <0 ; +help=Specifies the number of cells that are needed by the transport scheme at + =the edge of the model domain for limited area (non-periodic) configurations. + =This will depend on the choice of time splitting scheme. Recommended value + =for MoL with SSP3 is: + = + = transport_boundary_depth = 6 + = + =The recommended value for FFSL or SL schemes is to match the value of the + =dep_pt_stencil_extent namelist option. + =Note that the region with blending weights set to 1 should extend beyond + =this depth. + =This is only used for non-periodic domains. +!kind=default +ns=namelist/Science/Dynamics/Boundaries +range=0: +sort-key=Panel-A13 +type=integer + +[namelist:boundaries=transport_overwrite_freq] +compulsory=true +description=The frequency of LBC overwriting operations in transport schemes. +!enumeration=true +help=Overwriting transported fields in the LBC region during the transport + =scheme helps to enforce the LBCs. However there is a choice in the + =frequency that this can be performed. The options are, in increasing order + =of frequency: + = 'none' : No overwriting of transported fields + = 'final': Overwrite transported fields only at the end of the 3D transport + = of that field + = 'split_step': Overwrite transported fields at the end of each vertical + = or horizontal split transport step + = 'all': Overwrite transported fields after every transport calculation, + = including after the inner SWIFT steps and vertical transport. +ns=namelist/Science/Dynamics/Boundaries +sort-key=Panel-A14 +value-titles=None, Final, Split Step, All +values='none','final','split_step','all' + +#============================================================================== +# CHECKING CRITERIA +#============================================================================== +[namelist:checks] +compulsory=true +description=This namelist is used to add in runtime checks +help=See individual options for further help. +ns=namelist/Science/Dynamics/checks +sort-key=Section-A01 +title=Checking criteria + +[namelist:checks=limit_cfl] +compulsory=true +description=Limit the local advective Courant number +help=If true, then tests the local advective Courant number + =and if necessary reduces the wind components to ensure + =this doesn't exceed the limit given by max_cfl. #' + =Note that this will change the answers and is only + =designed to aid model development. It should not be + =used in operational rund. +!kind=default +sort-key=Panel-A01 +trigger=namelist:checks=max_cfl: .true. ; +type=logical + +[namelist:checks=max_cfl] +compulsory=true +description=Set the maximum advective Courant number. +fail-if=this <= 0.0 ; +help=If limit_cfl=.true., then this will be used to determine the maximum advective Courant number. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real +warn-if=this > 10.0 ; + +#============================================================================== +# DAMPING LAYER +#============================================================================== +[namelist:damping_layer] +compulsory=true +description=?????? +help=?????? + =?????? +ns=namelist/Science/Dynamics/Damping layer +sort-key=Section-A02 + +[namelist:damping_layer=dl_base] +compulsory=true +description=?????? +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=Base height of damping layer +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:damping_layer=dl_str] +compulsory=true +description=?????? +fail-if=this < 0.0 ; +help=Strength of damping layer +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[namelist:damping_layer=dl_type] +compulsory=true +description=Type of damping layer profile +!enumeration=true +help=Standard: Sine-squared profile above dl_base + =Latitude: Standard profile with cos(latitude) dip from equator to 50N/S. + = Poleward of 50N/S, profile is fixed at that of 50N/S. +sort-key=Panel-A03 +value-titles=Standard,Latitude +values='standard','latitude' + +#============================================================================== +# DEPARTURE POINTS +#============================================================================== +[namelist:departure_points] +compulsory=true +description=The method to calculate departure points. +help=This namelist selects the method to choose the departure points + =for the flux form semi-Lagrangian (FFSL) scheme and the vertical + =semi-Lagrangian and SLICE schemes. +ns=namelist/Science/Dynamics/departure_points +sort-key=Section-A03 +title=Departure points + +[namelist:departure_points=horizontal_limit] +compulsory=true +description=Method for handling the horizontal departure points that exceed the stencil extent. +!enumeration=true +fail-if=this=="'cap'" and namelist:departure_points=horizontal_method=="'midpoint'" + =this=="'cap'" and namelist:departure_points=horizontal_method=="'trapezoidal'" +help=Select option for how to deal with the horizontal departure points that lie beyond + =the specified departure point stencil extent: + =None : Do nothing if departure points exceed the stencil extent. + = This may result in the model failing. + =Cap : Cap the departure distance to lie within the stencil extent. + = This is equivalent to capping the advecting wind, and is only + = suitable for Eulerian horizontal departure points. +sort-key=Panel-A03 +value-titles=None, Cap +values='none', 'cap' + +[namelist:departure_points=horizontal_method] +compulsory=true +description=Method for calculating departure points in horizontal +!enumeration=true +fail-if= +help=Available horizontal departure point calculation choices: + =Eulerian: uses the new velocity at the arrival point. + =Trapezoidal: uses the old velocity interpolated to the estimated + =departure point and the new velocity at the arrival point. Only suitable + =for planar domain. + =Midpoint: interpolates the old velocity to halfway along the trajectory. + =Only suitable for planar domain. + =TimeAverage: averages the old and new velocities at the arrival point. + =FFSL: uses the time-averaged winds averaged at the arrival point, but takes + =the grid spacing into account using the volume of cells. +sort-key=Panel-A01 +value-titles=Eulerian, Trapezoidal, Midpoint, Time Average, FFSL +values='euler', 'trapezoidal', 'midpoint', 'timeaverage', 'ffsl' + +[namelist:departure_points=n_dep_pt_iterations] +compulsory=true +description=The number of iterations for the Trapezoidal and Midpoint methods. +fail-if= +help=The number of iterations for the Trapezoidal and Midpoint departure point + =calculation methods in both the horizontal and vertical. The departure point + =estimate converges quickly, and so only 2-3 iterations are usually required. +!kind=default +!range= +sort-key=Panel-A06 +type=integer + +[namelist:departure_points=share_stencil_extent] +compulsory=true +description=Whether to share the maximum extent of departure points between + =different sets of calculations. +help=The departure distances are used to set the size of stencils to use in + =corresponding horizontal transport calculations. Using the maximum + =departure distance to set the stencil size (rather than the maximum halo + =depth of the model) reduces the amount of parallel data communication + =required. However this requires a global min/max calculation on the + =departure distance field. + =If this option is set to true, the stencil size is shared between different + =horizontal calculations that use different departure distances. This + =reduces the number of min/max calculations required. +sort-key=Panel-A08 +type=logical + +[namelist:departure_points=vertical_limit] +compulsory=true +description=Method for correcting departure points that exceed the vertical domain. +!enumeration=true +fail-if= +help=Select option for how to deal with departure points that lie below the surface + =or above the model top: + =None : no capping is applied. + =Boundary : sets the departure point to the boundary value. + =Exponential: follows the method of Wood et al. (2009) to use an exponential + =function to force the departure point into the domain. +sort-key=Panel-A04 +value-titles=None, Boundary, Exponential +values='none', 'boundary', 'exponential' + +[namelist:departure_points=vertical_method] +compulsory=true +description=Method for calculating departure points in vertical. +!enumeration=true +fail-if= +help=Available vertical departure point calculation choices: + =Eulerian: uses the new velocity at the arrival point. + =Trapezoidal: uses the old velocity interpolated to the estimated + =departure point and the new velocity at the arrival point. + =Midpoint: interpolates the old velocity to halfway along the trajectory. + =TimeAverage: averages the old and new velocities at the arrival point. +sort-key=Panel-A02 +value-titles=Eulerian, Trapezoidal, Midpoint, Time Average +values='euler', 'trapezoidal', 'midpoint', 'timeaverage' + +[namelist:departure_points=vertical_sorting] +compulsory=true +description=Whether to sort vertical departure points +help=If true, the vertical departure points are sorted to be vertically + =increasing, so that vertical trajectories do not cross. +sort-key=Panel-A05 +type=logical + +#============================================================================== +# Energy correction for climate simulation +#============================================================================== +[namelist:energy_correction] +compulsory=true +description=Energy correction options +help=Implementation of Unified Model global energy correction, + =as described in UMDP85. +ns=namelist/Science/Energy correction +sort-key=Section-A02 +title=Energy correction + +[namelist:energy_correction=encorr_usage] +compulsory=true +description=Determines how energy correction is used +!enumeration=true +fail-if=this != "'none'" and namelist:base_mesh=geometry != "'spherical'" ; +help=None - energy correction not calculated. + =Diagnose - diagnose but do not apply energy correction. + =Apply - apply energy correction. +!kind=default +ns=namelist/Science/Energy correction +sort-key=Panel-A04 +trigger=namelist:energy_correction=reset_hours: this != "'none'"; +value-titles=None, Diagnose, Apply +values='none', 'diag', 'apply' + +[namelist:energy_correction=integral_method] +compulsory=true +description=Method for calculating global integrals of mass and total energy +!enumeration=true +help=Finite difference - this replicates the numerics used in UM(ENDGame). + =Finite element - use quadrature on the finite element representation of fields. + =The finite element method is computationally more expensive than the finite difference + =method but is more accurate, as it uses the correct cell shapes and applies quadrature + =to the finite element fields. +!kind=default +ns=namelist/Science/Energy correction +sort-key=Panel-A03a +value-titles=Finite difference, Finite element +values='fd', 'fe' + +[namelist:energy_correction=reset_hours] +compulsory=true +description=Number of hours between each reset of energy correction +help=Period over which energy correction applies a constant temperature increment. This increment + =is recalculated at the end of each period, to correct for the energy error incurred during + =that period. The energy error in a given period is the difference in total energy between + =the end and start of the period minus the accumulated net inward radiation. The period must + =comprise a whole number multiple of radiation steps. +!kind=default +ns=namelist/Science/Energy correction +sort-key=Panel-A03b +type=integer + +#============================================================================== +# ESM COUPLE (e.g. OASIS3-MCT) +#============================================================================== +[namelist:esm_couple] +compulsory=true +description=This namelist is used to control coupling operations + =between lfric and other Earth system model components. +help=See individual options for further help. +ns=namelist/Model/Coupling +sort-key=Section-A50 +title=Coupling controls + +[namelist:esm_couple=l_esm_couple_test] +compulsory=true +description=Test coupling exchanges? +help=Set to true in order to test coupling operations + =without using the incoming coupling field values to drive LFRic. + = + =Coupling "put" operations will be performed as normal. + = + =Coupling "get" operations will result in data + =being recieved but not used by LFRic. + = + =This should normally only be set to true for + =development and debugging purposes. + = + =This switch will have no effect if the model is compiled without + =the presence of a suitable coupler (e.g. OASIS3-MCT) +sort-key=Panel-A51 +type=logical + +#============================================================================== +# External forcing +#============================================================================== +[namelist:external_forcing] +compulsory=true +description=External forcing options +ns=namelist/Science/External Forcing +sort-key=Section-A13 +title=External forcing + +[namelist:external_forcing=diffusion_coefficient] +compulsory=true +description=The horizontal wind diffusion coefficient. +help=The horizontal wind diffusion coefficient (dimensionless). +!kind=default +ns=namelist/Science/External Forcing/Wind Forcing +sort-key=Panel-A02c +type=real + +[namelist:external_forcing=diffusion_order] +compulsory=true +description=Order of horizontal wind diffusion forcing +help=Number of successive diffusion operators to apply to horizontal wind on W2 +!kind=default +ns=namelist/Science/External Forcing/Wind Forcing +range=1:10 +sort-key=Panel-A02b +type=integer + +[namelist:external_forcing=filtering_order] +compulsory=true +description=Order or degree of wind filtering +help=Number of successive 1-2-1 filters to apply to horizontal wind on W2 +!kind=default +ns=namelist/Science/External Forcing/Wind Forcing +range=1:10 +sort-key=Panel-A02a +type=integer + +[namelist:external_forcing=geostrophic_forcing] +compulsory=true +description=Switch on geostrophic forcing of wind +help=Switch on geostrophic wind forcing. + =Further details must be supplied on the subsequent geostrophic wind + =forcing panel. +!kind=default +ns=namelist/Science/External Forcing +sort-key=C3 +trigger=namelist:geostrophic_forcing: this == ".true."; +type=logical + +[namelist:external_forcing=hs_random] +compulsory=true +description=Random perturbations to the Held-Suarez theta forcing +help=Option to add in random perturbations to the Held-Suarez theta forcing: + = After the calculation of the theta increment, this will be multiplied + = by a factor (1 + 0.0001*(p - 0.5)), where p is a random number taken from + = a Uniform distribution on [0,1]. + = Note, this is for model development purposes. +!kind=default +ns=namelist/Science/External Forcing/Temperature Forcing +sort-key=Panel-A01a +type=logical + +[namelist:external_forcing=pc2_force_response] +compulsory=true +description=Include PC2 response to external forcing +help=If true, then a PC2 homogeneous forcing response will be applied to any + = external forcing which is included +!kind=default +ns=namelist/Science/External Forcing +sort-key=E1 +type=logical + +[namelist:external_forcing=theta_forcing] +compulsory=true +description=Options for external forcing of potential temperature (theta) +!enumeration=true +help=Available forcing options are: + =Held-Suarez theta forcing term, based on Wedi and Smolarkiewicz (2009), + = A framework for testing global non-hydrostatic models. + = Q.J.R. Meteorol. Soc., 135: 469-484. DOI: 10.1002/qj.377. + =Theta forcing term for the Earth-Like and Hot-Jupiter tests based on + = Menou & Rauscher (2009), Atmospheric Circulation of Hot Jupiters: A Shallow + = Three-Dimensional Model, ApJ, 700, 887-897, DOI: 10.1088/0004-637X/700/1/887, + = and Tidally-Locked forcing based on Merlis and Schneider (2010), + = Atmospheric Dynamics of Earth-Like Tidally Locked Aquaplanets, + = Journal of Advances in Modeling Earth Systems, 2, 13, + = DOI: 10.1029/JAMES.2010.2.13. + =Tidally Locked Earth (TLE) theta forcing based on Merlis, T. M., and + = Schneider, T. (2010), Atmospheric Dynamics of Earth-Like Tidally Locked + = Aquaplanets, J. Adv. Model. Earth Syst., 2, 13, doi:10.3894/JAMES.2010.2.13. + =Temperature tendency profile: apply a specified profile of heating rates +!kind=default +ns=namelist/Science/External Forcing +sort-key=A1 +trigger=namelist:external_forcing=hs_random: this == "'held_suarez'" ; + =namelist:temp_tend_data: this == "'temp_tend'"; + =namelist:external_forcing=pc2_force_response: this != "'none'"; +value-titles=None, Held-Suarez, Earth-Like, Tidally Locked Earth, Shallow Hot Jupiter, Deep Hot Jupiter, Temperature Tendency Profile +values='none', 'held_suarez', 'earth_like', 'tidally_locked_earth', 'shallow_hot_jupiter', 'deep_hot_jupiter', 'temp_tend' + +[namelist:external_forcing=theta_relaxation] +compulsory=true +description=Switch on relaxation forcing of theta +help=Newtonian relaxation is applied to potential temperature, + = d(theta)/dt = -(theta - theta_target) / tau, + =where tau is specified in seconds using theta_relax:timescale. + =The target vertical profile, towards which potential temperature is relaxed, + =is specified in the theta_relax:profile_data array. This contains values of the + =profile at the corresponding heights contained in the theta_relax:heights + =array. Linear interpolation is used to map the profile onto the vertical + =grid as defined in the extrusion namelist. + =The target profile may change in time and this is done by listing + =the target profile data sequentially in theta_relax:profile_data, with the validity + =times of these profiles specified in theta_relax:times. It is essential to + =correctly specify the number of elements in the height and time arrays, + =using the variables theta_relax:number_heights and theta_relax:number_times, respectively. +!kind=default +ns=namelist/Science/External Forcing +sort-key=A2 +trigger=namelist:theta_relax: this == ".true."; +type=logical + +[namelist:external_forcing=vapour_forcing] +compulsory=true +description=Options for external forcing of vapour mixing ratio +!enumeration=true +help=Available forcing options for water vapour are: + = + =Apply specified profile of mixing ratio tendency. + = + =Further details must be supplied on the subsequent vapour forcing panel. +!kind=default +ns=namelist/Science/External Forcing +sort-key=B1 +trigger=namelist:vapour_forcing: this == "'profile'" ; +value-titles=None, Profile +values='none', 'profile' + +[namelist:external_forcing=vertadvect_forcing] +compulsory=true +description=Switch on vertical advection forcing +help=If true, advection increments from a specified vertical velocity + =profile are calculated, for theta, water vapour, liquid water mixing + =ratio and horizontal wind components, as must be specified in the + =subsequent vertical advection forcing panel. +!kind=default +ns=namelist/Science/External Forcing +sort-key=D1 +trigger=namelist:vertadvect: this == ".true."; +type=logical + +[namelist:external_forcing=wind_forcing] +compulsory=true +description=Options for external forcing of the horizontal wind +!enumeration=true +help=Available forcing options for the horizontal components of the wind are: + = + =Held-Suarez wind forcing term, based on Wedi and Smolarkiewicz (2009) + = A framework for testing global non-hydrostatic models. + = Q.J.R. Meteorol. Soc., 135: 469-484. DOI: 10.1002/qj.377. + = + =Apply successive diffusion or 1-2-1 filters to horizontal winds on W2. + = + =Apply specified profiles of horizontal wind component tendencies. + = + =Further details must be supplied on the subsequent horizontal wind + =forcing panel. +!kind=default +ns=namelist/Science/External Forcing +sort-key=C1 +trigger=namelist:external_forcing=filtering_order: this == "'filtering'"; + =namelist:external_forcing=diffusion_order: this == "'diffusion'"; + =namelist:external_forcing=diffusion_coefficient: this == "'diffusion'"; + =namelist:wind_forcing: this == "'profile'"; +value-titles=None, Held-Suarez, Filtering, Diffusion, Profile +values='none','held_suarez', 'filtering', 'diffusion', 'profile' + +[namelist:files] +compulsory=true +description=Sets up options for files +help=?????? + =?????? +ns=namelist/Job/IO +sort-key=sec-AAAA + +[namelist:files=aerosols_ancil_path] +compulsory=true +description=Path to aerosols file from ancillary files directory +help=This file contains the aerosols data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=albedo_nir_ancil_path] +compulsory=true +description=Path to near-IR albedo file from ancillary files directory +help=This file contains the near-IR albedo data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=albedo_vis_ancil_path] +compulsory=true +description=Path to visible albedo file from ancillary files directory +help=This file contains the visible albedo data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=ancil_directory] +compulsory=true +description=Directory for ancillary files +help=Path to the directory where LFRic ancillaries are stored +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=checkpoint_stem_name] +compulsory=true +description=Filename stem for checkpoint files +help=Filename stem for checkpoint files +ns=namelist/Job/IO/Checkpointing & Restart +sort-key=A-007 +!string_length=filename +type=character + +[namelist:files=cloud_drop_no_conc_ancil_path] +compulsory=true +description=Path to EasyAerosol ancillary files directory +help=This file contains a climatology of cloud droplet number + =concentrations. +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=coarse_ancil_directory] +compulsory=true +description=Directory for coarse ancillary files +help=Path to the directory where coarse LFRic ancillaries are stored +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=diag_stem_name] +compulsory=true +description=Filename stem for diagnostic files +help=Filename stem for diagnostic files +ns=namelist/Job/IO/Diagnostics +sort-key=Panel-A02 +!string_length=filename +type=character + +[namelist:files=dms_conc_ocean_ancil_path] +compulsory=true +description=Path to DMS (surface) concentrations in ocean in ancil directory +help=This file contains the DiMethyl Sulphide (DMS) concentrations for + = aerosols, generated at the ocean surface, which feed into DMS emissions +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=ea_ancil_directory] +compulsory=true +description=Directory for ancillary files +help=Path to the directory where LFRic ancillaries are stored +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=easy_absorption_lw_ancil_path] +compulsory=true +description=Path to EasyAerosol ancillary files directory +help=This file contains a climatology of the aerosol absorption coefficient + =for the longwave wavebands. +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=easy_absorption_sw_ancil_path] +compulsory=true +description=Path to EasyAerosol ancillary files directory +help=This file contains a climatology of the aerosol absorption coefficient + =for the shortwave wavebands. +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=easy_asymmetry_lw_ancil_path] +compulsory=true +description=Path to EasyAerosol ancillary files directory +help=This file contains a climatology of the aerosol asymmetry parameter + =for the longwave wavebands. +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=easy_asymmetry_sw_ancil_path] +compulsory=true +description=Path to EasyAerosol ancillary files directory +help=This file contains a climatology of the aerosol asymmetry parameter + =for the shortwave wavebands. +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=easy_extinction_lw_ancil_path] +compulsory=true +description=Path to EasyAerosol ancillary files directory +help=This file contains a climatology of the aerosol extinction coefficient + =for the longwave wavebands. +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=easy_extinction_sw_ancil_path] +compulsory=true +description=Path to EasyAerosol ancillary files directory +help=This file contains a climatology of the aerosol extinction coefficient + =for the shortwave wavebands. +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_bc_biofuel_ancil_path] +compulsory=true +description=Path to BC biofuel emissions from ancillary files directory +help=This file contains the Black Carbon (BC) surface aerosol emissions + = generated from biofuels +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_bc_biomass_ancil_path] +compulsory=true +description=Path to BC biomass emissions from ancillary files directory +help=This file contains the Black Carbon (BC) (3-D) aerosol emissions + = generated from biomass burning, incl. forest fires +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_bc_biomass_hi_ancil_path] +compulsory=true +description=Path to high-level BC biomass emissions +help=This file contains the Black Carbon (BC) upper-level aerosol emissions + = generated from biomass burning, incl. forest fires +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_bc_biomass_lo_ancil_path] +compulsory=true +description=Path to low-level BC biomass emissions +help=This file contains the Black Carbon (BC) surface aerosol emissions + = generated from biomass burning, incl. forest fires +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_bc_fossil_ancil_path] +compulsory=true +description=Path to BC fossil fuel emissions from ancillary files directory +help=This file contains the Black Carbon (BC) surface aerosol emissions + = generated from fossil fuels +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_c2h6_ancil_path] +compulsory=true +description=Path to C2H6 (surface) emissions in ancil directory +help=This file contains the C2H6 surf emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_c3h8_ancil_path] +compulsory=true +description=Path to C3H8 (surface) emissions in ancil directory +help=This file contains the C3H8 surf emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_c5h8_ancil_path] +compulsory=true +description=Path to C5H8 (surface) emissions in ancil directory +help=This file contains the Biogenic surface C5H8 emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_ch4_ancil_path] +compulsory=true +description=Path to CH4 (surface) emissions in ancil directory +help=This file contains the CH4 surf emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_co_ancil_path] +compulsory=true +description=Path to CO (surface) emissions in ancil directory +help=This file contains the CO surf emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_dms_land_ancil_path] +compulsory=true +description=Path to DMS (surface) emissions over land from ancillary directory +help=This file contains the DiMethyl Sulphide surface aerosol emissions + = generated over land +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_hcho_ancil_path] +compulsory=true +description=Path to HCHO (surface) emissions in ancil directory +help=This file contains the HCHO surf emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_me2co_ancil_path] +compulsory=true +description=Path to ME2CO (surface) emissions in ancil directory +help=This file contains the Me2CO surf emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_mecho_ancil_path] +compulsory=true +description=Path to MECHO (surface) emissions in ancil directory +help=This file contains the MeCHO surf emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_meoh_ancil_path] +compulsory=true +description=Path to MEOH (surface) emissions in ancil directory +help=This file contains the Biogenic surface methanol (CH3OH) emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_monoterp_ancil_path] +compulsory=true +description=Path to Monoterpene (surface) emissions from ancillary directory +help=This file contains the Monoterpene surface aerosol emissions +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_murk_ancil_path] +compulsory=true +description=Path to Murk emissions from ancillary directory +help=This file contains the Murk aerosol emissions +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_nh3_ancil_path] +compulsory=true +description=Path to NH3 (surface) emissions in ancil directory +help=This file contains the ammonia gas emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_no_aircrft_ancil_path] +compulsory=true +description=Path to NO_AIRCRFT (3-D) emissions in ancil directory +help=This file contains the NOx aircraft emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_no_ancil_path] +compulsory=true +description=Path to NO (surface) emissions in ancil directory +help=This file contains the NOx surface emissions for chemistry +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_om_biofuel_ancil_path] +compulsory=true +description=Path to OC biofuel emissions from ancillary files directory +help=This file contains the Organic Carbon (OC) surface aerosol emissions + = generated from biofuels +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_om_biomass_ancil_path] +compulsory=true +description=Path to OC biomass emissions from ancillary files directory +help=This file contains the Organic Carbon (OC) (3-D) aerosol emissions + = generated from biomass burning, incl. forest fires +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_om_biomass_hi_ancil_path] +compulsory=true +description=Path to high-level OC biomass emissions +help=This file contains the Organic Carbon (OC) high-level aerosol emissions + = generated from biomass burning, incl. forest fires +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_om_biomass_lo_ancil_path] +compulsory=true +description=Path to OC low-level biomass emissions +help=This file contains the Organic Carbon (OC) surface aerosol emissions + = generated from biomass burning, incl. forest fires +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_om_fossil_ancil_path] +compulsory=true +description=Path to OC fossil fuel emissions from ancillary files directory +help=This file contains the Organic Carbon (OC) surface aerosol emissions + = generated from fossil fuels +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_so2_high_ancil_path] +compulsory=true +description=Path to SO2-high emission from ancillary files directory +help=This file contains the SO2 high (but fixed-level) aerosol emissions + = generated by industrial sources/ shipping +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_so2_low_ancil_path] +compulsory=true +description=Path to SO2-low emission from ancillary files directory +help=This file contains the SO2 low surface aerosol emissions +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=emiss_so2_nat_ancil_path] +compulsory=true +description=Path to SO2-natural emission from ancillary files directory +help=This file contains the natural SO2 (3D) emissions for aerosols +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=gas_mmr_ancil_path] +compulsory=true +description=Path to gas MMRs (3-D) in ancil directory +help=This file contains the gas MMRs for the idealised/flexchem scheme +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=h2o2_limit_ancil_path] +compulsory=true +description=Path to H2O2 (limiting oxidant) file from ancillary files directory +help=This file contains the H2O2 (hydrogen peroxide) mass mixing ratio data + = required to run GLOMAP aerosols in Offline mode +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=ho2_ancil_path] +compulsory=true +description=Path to HO2 (oxidant) file from ancillary files directory +help=This file contains the HO2 (hydroperoxy radical) mass mixing ratio data + = required to run GLOMAP aerosols in Offline mode +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=hydtop_ancil_path] +compulsory=true +description=Path to TOPMODEL hydrology file from ancillary files directory +help=This file contains the topographic index data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=iau_addinf_path] +compulsory=true +description=Path to the IAU addinf file +help=This file contains the first set of additive inflation increments + = for the IAU +ns=namelist/Job/IO/IAU +!string_length=filename +type=character + +[namelist:files=iau_bcorr_path] +compulsory=true +description=Path to the IAU bcorr file +help=This file contains the first set of bias correction increments + = for the IAU +ns=namelist/Job/IO/IAU +!string_length=filename +type=character + +[namelist:files=iau_path] +compulsory=true +description=Path to the IAU file +help=This file contains the analysis increments for the IAU +ns=namelist/Job/IO/IAU +!string_length=filename +type=character + +[namelist:files=iau_pert_path] +compulsory=true +description=Path to the IAU pert inc file +help=This file contains analysis increments from the perturbation members + = of the control-pert DA ensemble for the IAU +ns=namelist/Job/IO/IAU +!string_length=filename +type=character + +[namelist:files=iau_sst_path] +compulsory=true +description=Path to the sst IAU file +help=This file contains SST perturbations from the ensemble for use by the IAU +ns=namelist/Job/IO/IAU +!string_length=filename +type=character + +[namelist:files=iau_surf_path] +compulsory=true +description=Path to the surf IAU file +help=This path contains the IAU surf file +ns=namelist/Job/IO/IAU +!string_length=filename +type=character + +[namelist:files=internal_flux_ancil_path] +compulsory=true +description=Path to an internal flux 2D map in ancil directory +help=This file contains the internal flux data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=land_area_ancil_path] +compulsory=true +description=Path to land area fraction file from ancillary files directory +help=This file contains the land area fraction data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=lbc_directory] +compulsory=true +description=Path to lbc directory +help=This directory contains the lbc file +ns=namelist/Job/IO/LBCs +!string_length=filename +type=character + +[namelist:files=lbc_filename] +compulsory=true +description=Path to lbc file +help=This file contains the lbc data +ns=namelist/Job/IO/LBCs +!string_length=filename +type=character + +[namelist:files=ls_directory] +compulsory=true +description=Path to the linearisation state directory +help=This directory contains the linearisation state file +ns=namelist/Job/IO/LS +!string_length=filename +type=character + +[namelist:files=ls_filename] +compulsory=true +description=Path to the linearisation state file +help=This file contains the linearisation state data +ns=namelist/Job/IO/LS +!string_length=filename +type=character + +[namelist:files=no3_ancil_path] +compulsory=true +description=Path to NO3 (oxidant) file from ancillary files directory +help=This file contains the NO3 (nitrate radical) mass mixing ratio data + = required to run GLOMAP aerosols in Offline mode +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=o3_ancil_path] +compulsory=true +description=Path to O3 (oxidant) file from ancillary files directory +help=This file contains the O3 (ozone) mass mixing ratio data + = required to run GLOMAP aerosols in Offline mode +ns=namelist/Job/IO/Ancils +type=character + +[namelist:files=oh_ancil_path] +compulsory=true +description=Path to OH (oxidant) file from ancillary files directory +help=This file contains the OH (hydroxl radical) mass mixing ratio data + = required to run GLOMAP aerosols in Offline mode +ns=namelist/Job/IO/Ancils +type=character + +[namelist:files=orography_mean_ancil_path] +compulsory=true +description=Path to mean orography file from ancillary files directory +help=This file contains global surface altitude information used for orography +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=orography_subgrid_ancil_path] +compulsory=true +description=Path to subgrid orography file from ancillary files directory +help=This file contains subgrid orographic information used by parametrizations +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=ozone_ancil_path] +compulsory=true +description=Path to Ozone file from ancillary files directory +help=This file contains the ozone mass mixing ratio data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=plant_func_ancil_path] +compulsory=true +description=Path to plant functional type file from ancillary files directory +help=This file contains the canopy height and leaf area index +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=sea_ancil_path] +compulsory=true +description=Path to sea file from ancillary files directory +help=This file contains the sea surface chlorophyll concentration +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=sea_ice_ancil_path] +compulsory=true +description=Path to sea ice file from ancillary files directory +help=This file contains the sea ice thickness and fraction +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=snow_analysis_ancil_path] +compulsory=true +description=Path to snow file from ancillary files directory +help=This file contains the snow analysis data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=soil_ancil_path] +compulsory=true +description=Path to soil file from ancillary files directory +help=This file contains the soil data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=soil_dust_ancil_path] +compulsory=true +description=Path to soil inputs for dust from ancil files directory +help=This file contains the soil properties required for dust emissions +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=soil_rough_ancil_path] +compulsory=true +description=Path to soil roughness file from ancillary files directory +help=This file contains the soil roughness data +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=sst_ancil_path] +compulsory=true +description=Path to sst file from ancillary files directory +help=This file contains the sea surface temperature +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=start_dump_directory] +compulsory=true +description=Directory for start dumps +help=?????? +ns=namelist/Job/IO/Dumping +!string_length=filename +type=character + +[namelist:files=start_dump_filename] +compulsory=true +description=Filename for start dump +help=?????? +ns=namelist/Job/IO/Dumping +!string_length=filename +type=character + +[namelist:files=surface_frac_ancil_path] +compulsory=true +description=Path to surface types fraction file from ancillary files directory +help=This file contains the fractions of different surface types +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +[namelist:files=urban_ancil_path] +compulsory=true +description=Path to urban file from ancillary files directory +help=This file contains information on building size for the urban schemes +ns=namelist/Job/IO/Ancils +!string_length=filename +type=character + +#============================================================================== +# FINITE ELEMENT +#============================================================================== +[namelist:finite_element=vorticity_in_w1] +compulsory=true +description=?????? +help=Compute the vorticity in W1 (or implied W2) space +!kind=default +sort-key=Panel-A07 +type=logical + +#============================================================================== +# DYNAMICS +#============================================================================== +# +#============================================================================== +# FORMULATION +#============================================================================== +[namelist:formulation] +compulsory=true +description=Dynamics options +help=Options for dynamics formulation and numerics +ns=namelist/Science/Dynamics +sort-key=B +title=Dynamics + +[namelist:formulation=dlayer_on] +compulsory=true +description=Damping layer switch +help=Use damping layer yes/no +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A07 +trigger=namelist:damping_layer: .true. ; +type=logical + +[namelist:formulation=dry_static_adjust] +compulsory=true +description=Dry static adjustment of reference profile +help=Apply a sorting algorithm to each column of the + =potential temperature semi-implicit reference profile, + =ensuring that it is monotonically increasing with height. + =Without this the semi-implicit Helmholtz equation may + =be ill-posed. +!kind=default +sort-key=Panel-A06 +type=logical + +[namelist:formulation=eos_method] +compulsory=true +description=Method used to treat equation of state (EoS). This method will + =be used consistently throughout the model +!enumeration=true +help=Two methods are available for treating the EoS: + ='sampled' - Sampled at finite element data points + ='projected' - Galerkin projected onto finite element representation +sort-key=Panel-A12 +value-titles=Sampled at data points, Projected onto elements +values='sampled', 'projected' + +[namelist:formulation=exner_from_eos] +compulsory=true +description=Recompute Exner pressure after each solve +help=Diagnose the Exner pressure function from the equation of state + =after each mixed solve +!kind=default +sort-key=Panel-A11 +type=logical + +[namelist:formulation=horizontal_physics_predictor] +compulsory=true +description=Only use the horizontal component when computing + =the wind physics predictors +help=If true only the horizontal component of the RHS terms + =will be used when computing the physics wind predictor +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A12 +type=logical + +[namelist:formulation=horizontal_transport_predictor] +compulsory=true +description=Only use the horizontal component when computing + =the wind transport predictors +help=If true only the horizontal component of the RHS will be + =used when computing the transport wind predictor +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A12 +type=logical + +[namelist:formulation=init_exner_bt] +compulsory=true +description=?????? +help=Initialize exner hydrostatically bottom to top +!kind=default +sort-key=Panel-A10 +type=logical + +[namelist:formulation=l_multigrid] +compulsory=true +description=Enable Multi-Grid +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A01 +trigger=namelist:multigrid: .true. ; +type=logical + +[namelist:formulation=lagged_orog] +compulsory=true +description=Lag sloped/bent orography terms on the right hand side. +help=This is achieved by omitting the vertical-horizontal correlations from + =the W2 mass-matrix in the mixed-solve, but keeping them in the W2 + =mass-matrix used to create the RHS. Then the vertical-horizontal + =correlations are evaluated at iteration i rather than at iteration + =i+1 i.e. they are lagged. +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A01 +type=logical + +[namelist:formulation=moisture_formulation] +compulsory=true +description=Select behaviour of moisture fields +!enumeration=true +help=Dry: Moisture fields set to zero, have no effect on dynamics and are not transported. + =Passive: Moisture fields transported as passive tracers. + =Active: Moisture fields transported as active tracers, with their inertia + = affecting the dynamics. + =Traditional: Traditional treatment of moist dynamics. Moisture fields are transported, + = their inertia affects dynamics, and vapour pressure is + = accounted for in the equation of state and pressure gradients. +ns=namelist/Science +sort-key=Panel-A02 +trigger=namelist:section_choice=aerosol: 'traditional' ; + =namelist:section_choice=cloud: 'traditional' ; + =namelist:section_choice=methane_oxidation: 'traditional' ; + =namelist:section_choice=microphysics: 'traditional' ; + =namelist:formulation=theta_moist_source: 'traditional' ; +value-titles=Dry, Passive tracers, Active tracers, Traditional approximations +values='dry', 'passive', 'active', 'traditional' + +[namelist:formulation=moisture_in_solver] +compulsory=true +description=Whether to include contributions from moisture variables to the + =pressure gradient term in the linear solver +help=If true, moisture weights are included in the pressure gradient in the + =linear solver. + =If false, then impact of moisture on pressure gradient is ignored. +!kind=default +sort-key=Panel-A07 +type=logical + +[namelist:formulation=p2theta_vert] +compulsory=true +description=Only use vertical parts in projection operators from + =temperature to velocity space +help=If true, then only use vertical parts in projection operators from + =temperature to velocity space. + =If false, then use all components in projection operators from + =temperature to velocity space. +!kind=default +sort-key=Panel-A11 +type=logical + +[namelist:formulation=rotating] +compulsory=true +description=Include Coriolis terms +help=Turn on/off Coriolis terms +!kind=default +sort-key=Panel-A03 +type=logical + +[namelist:formulation=shallow] +compulsory=true +description=Constant gravity +help=When true, the gravitational field is constant, as would be the under the shallow + =atmosphere approximation. When false, gravity varies as inverse square of radial distance + =from planet centre. +!kind=default +sort-key=Panel-A04 +type=logical + +[namelist:formulation=si_momentum_equation] +compulsory=true +description=Use a semi-implicit or explicit computation + =of the momentum equation. +help=Set .true. to use semi-implicit or + =set .false. to use an explicit treatment +!kind=default +sort-key=Panel-A13 +type=logical + +[namelist:formulation=theta_moist_source] +compulsory=false +description=Explicitly includes the source term to the potential temperature + =equation that relates to the difference in heat capacities between + =different moisture phases. +help=Adds a pointwise Crank-Nicolson discretisation of the moist source term + =to the potential temperature equation, which is applied after transporting + =the potential temperature. This does nothing if the transported theta + =variable is the 'moist' potential temperature. This variable is only active + =if the moisture_formulation is set to 'traditional'. +!kind=default +sort-key=Panel-A02 +type=logical + +[namelist:formulation=use_multires_coupling] +compulsory=true +description=Enable use of multiple resolution meshes for coupling +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A11 +trigger=namelist:multires_coupling: .true. ; + =namelist:multires_coupling=lowest_order_aero_flag: .true. ; +type=logical + +[namelist:formulation=use_physics] +compulsory=true +description=Use subgrid physics parametrizations or forcing terms +help=Use subgrid physics parametrizations or forcing terms +!kind=default +ns=namelist/Science +sort-key=Panel-A01 +trigger=namelist:section_choice=aerosol: .true. ; + =namelist:section_choice=boundary_layer: .true. ; + =namelist:section_choice=chemistry: .true. ; + =namelist:section_choice=cloud: .true. ; + =namelist:section_choice=electric: .true. ; + =namelist:section_choice=methane_oxidation: .true. ; + =namelist:section_choice=microphysics: .true. ; + =namelist:section_choice=orographic_drag: .true. ; + =namelist:section_choice=radiation: .true. ; + =namelist:section_choice=spectral_gwd: .true. ; + =namelist:section_choice=surface: .true. ; + =namelist:physics=sample_physics_scalars: .true. ; + =namelist:physics=sample_physics_winds: .true. ; + =namelist:physics=limit_drag_incs: .true. ; + =namelist:section_choice=stochastic_physics: .true. ; +type=logical + +[namelist:formulation=use_wavedynamics] +compulsory=true +description=Dynamics switch +help=This switch is for the wave-dynamics (adjustment) part of + =the dynamical core. When set to false, advection remains + =active. +!kind=default +sort-key=Panel-A05 +type=logical + +[namelist:formulation=vector_invariant] +compulsory=true +description=Use a vector invariant or advective form + =for the momentum equation. +help=Set .true. to use vector invariant or + =set .false. to use advective +!kind=default +sort-key=Panel-A14 +type=logical + +#============================================================================== +# GEOSTROPHIC FORCING OF HORIZONTAL WIND COMPONENTS +#============================================================================== +[namelist:geostrophic_forcing] +compulsory=true +description=Settings for geostrophic wind forcing +ns=namelist/Science/External Forcing/Geostrophic Forcing +sort-key=C3 +title=Geostrophic forcing + +[namelist:geostrophic_forcing=coordinate] +compulsory=true +description=Vertical coordinate for geostrophic wind forcing +!enumeration=true +help=Geostrophic wind profiles may be specified with either height + =or pressure as the vertical coordinate. In both cases the coordinate + =information is entered using the heights array. + =Height: height in metres above sea-level. Values should be monotonically increasing. + =Pressure: pressure level in Pascals. Values should be monotonically decreasing. +!kind=default +ns=namelist/Science/External Forcing/Geostrophic Forcing +sort-key=Panel-A01b +value-titles=Height, Pressure +values='height', 'pressure' + +[namelist:geostrophic_forcing=heights] +!bounds=namelist:geostrophic_forcing=number_heights +compulsory=true +description=Heights of points in geostrophic wind profiles +fail-if=len(this) != namelist:geostrophic_forcing=number_heights +help=Heights for geostrophic wind profiles. If in ascending order, these are + =taken to be height in metres. Heights specified in descending order are + =taken to be pressure coordinate in Pascals. +!kind=default +length=: +ns=namelist/Science/External Forcing/Geostrophic Forcing +sort-key=Panel-A01c +type=real + +[namelist:geostrophic_forcing=number_heights] +compulsory=true +description=Number of points in each geostrophic wind profile +help= +!kind=default +ns=namelist/Science/External Forcing/Geostrophic Forcing +range=0:100 +sort-key=Panel-A01a +type=integer + +[namelist:geostrophic_forcing=number_times] +compulsory=true +description=Number of geostrophic wind profiles +help= +!kind=default +ns=namelist/Science/External Forcing/Geostrophic Forcing +range=0:100 +sort-key=Panel-A01a +type=integer + +[namelist:geostrophic_forcing=profile_data_u] +!bounds=namelist:geostrophic_forcing=number_heights * namelist:geostrophic_forcing=number_times +compulsory=true +description=Geostrophic wind data +fail-if=len(this) != namelist:geostrophic_forcing=number_heights * namelist:geostrophic_forcing=number_times +help=U-component of geostrophic wind (m/s) +!kind=default +length=: +ns=namelist/Science/External Forcing/Geostrophic Forcing +sort-key=Panel-A01d +type=real + +[namelist:geostrophic_forcing=profile_data_v] +!bounds=namelist:geostrophic_forcing=number_heights * namelist:geostrophic_forcing=number_times +compulsory=true +description=Geostrophic wind data +fail-if=len(this) != namelist:geostrophic_forcing=number_heights * namelist:geostrophic_forcing=number_times +help=V-component of the geostrophic wind (m/s) +!kind=default +length=: +ns=namelist/Science/External Forcing/Geostrophic Forcing +sort-key=Panel-A01d +type=real + +[namelist:geostrophic_forcing=times] +!bounds=namelist:geostrophic_forcing=number_times +compulsory=true +description=Validity times of geostrophic wind profiles +fail-if=len(this) != namelist:geostrophic_forcing=number_times +help= +!kind=default +length=: +ns=namelist/Science/External Forcing/Geostrophic Forcing +sort-key=Panel-A01c +type=real + +#============================================================================== +# HELMHOLTZ SOLVER +#============================================================================== +[namelist:helmholtz_solver] +compulsory=true +description=?????? +help=This namelist contains the options for the preconditioner (helmholtz) solver +!kind=default +ns=namelist/Science/Dynamics/helmholtz solver +sort-key=Section-A08 +title=Pre-conditioner solver + +[namelist:helmholtz_solver=fail_on_non_converged] +compulsory=true +description=Cause the solver to return an error if the maximum number of iterations are reached and + =residual has not been reduced below the desired tolerance otherwise the solver will exit even + =if it has not converged. If monitor_convergence is set to false then this setting has no effect +help=Return an error if solver fails to converge +sort-key=Panel-A07 +type=logical + +[namelist:helmholtz_solver=gcrk] +compulsory=true +description=?????? +help=Dimension of the approximate Krylov subspace. + =In other words, it is the number of potential + =residual vectors to calculate at each + =iteration of the solver. +!kind=default +sort-key=Panel-A06 +type=integer + +[namelist:helmholtz_solver=jacobi_relaxation] +compulsory=true +description=?????? +help=Relaxtion factor to use in the Jacobi solver +!kind=default +sort-key=Panel-A11 +type=real + +[namelist:helmholtz_solver=method] +compulsory=true +description=?????? +!enumeration=true +help=?????? + =?????? +sort-key=Panel-A01 +trigger=namelist:helmholtz_solver=jacobi_relaxation: this == "'jacobi'"; +value-titles=biconjugate gradient stabilized, + =conjugate gradient, + =generalized conjugate residual, + =generalized minimal residual, + =flexible generalized minimal residual, + =precondition only, + =jacobi +values='bicgstab', 'cg', 'gcr', 'gmres', 'fgmres', 'prec_only', 'jacobi' + +[namelist:helmholtz_solver=monitor_convergence] +compulsory=true +description=Computes and prints out convergence information for the iterative solver and if the + =error has been reduced below the tolerance then the solver will exit. If set to false + =the solver will always perform the maximum number of iterations before exiting +help=Monitor convergence of the iterative Helmholtz solver +sort-key=Panel-A06 +trigger=namelist:helmholtz_solver=fail_on_non_converged: .true.; +type=logical + +[namelist:helmholtz_solver=normalise] +compulsory=true +description=?????? +help=Normalise Helmholtz matrix by its approximate diagonal +!kind=default +sort-key=Panel-A05 +type=logical + +[namelist:helmholtz_solver=preconditioner] +compulsory=true +description=?????? +!enumeration=true +fail-if=this == "'multigrid'" and namelist:formulation=l_multigrid == ".false." ; +help=?????? + =?????? +sort-key=Panel-A03 +value-titles=None, Diagonal, Tridiagonal, Multigrid +values='none', 'diagonal', 'tridiagonal', 'multigrid' + +[namelist:helmholtz_solver=si_pressure_a_tol] +compulsory=true +description=?????? +help=Absolute tolerance of semi-implicit pressure solver +!kind=default +sort-key=Panel-A03 +type=real + +[namelist:helmholtz_solver=si_pressure_maximum_iterations] +compulsory=true +description=?????? +fail-if=this < 1 ; +help=Iteration limit for si preconditioner solver +!kind=default +range=1: +sort-key=Panel-A04 +type=integer + +[namelist:helmholtz_solver=si_pressure_tolerance] +compulsory=true +description=?????? +help=Relative tolerance of semi-implicit pressure solver +!kind=default +sort-key=Panel-A02 +type=real + +#============================================================================== +# IAU MULTIFILE IO +#============================================================================== +[namelist:iau_addinf_io] +compulsory=false +description=This namelist contains the settings for use + =in IAU multifile IO for additive inflation +duplicate=true +!instance_key_member=filename +ns=namelist/Job/IO/IAU/Addinf +sort-key=Section-A05 + +[namelist:iau_addinf_io=filename] +compulsory=true +description=Filename for multifile IO additive inflation +!kind=default +type=character + +[namelist:iau_addinf_io=start_time] +compulsory=true +description=Time to read from additive inflation file(s) +help=Time in seconds from the start of the model run to + = open and read from additive inflation file(s) +!kind=default +type=integer + +[namelist:iau_ainc_io] +compulsory=false +description=This namelist contains the settings for use + =in IAU multifile IO for analysis increments +duplicate=true +!instance_key_member=filename +ns=namelist/Job/IO/IAU/Ainc +sort-key=Section-A05 + +[namelist:iau_ainc_io=filename] +compulsory=true +description=Filename for multifile IO analysis increments +!kind=default +type=character + +[namelist:iau_ainc_io=start_time] +compulsory=true +description=Time to read from analysis increments file(s) +help=Time in seconds from the start of the model run to + = open and read from analysis increment file(s) +!kind=default +type=integer + +[namelist:iau_bcorr_io] +compulsory=false +description=This namelist contains the settings for use + =in IAU multifile IO for bias correction +duplicate=true +!instance_key_member=filename +ns=namelist/Job/IO/IAU/Bcorr +sort-key=Section-A05 + +[namelist:iau_bcorr_io=filename] +compulsory=true +description=Filename for multifile IO bias correction +!kind=default +type=character + +[namelist:iau_bcorr_io=start_time] +compulsory=true +description=Time to read from bias correction file(s) +help=Time in seconds from the start of the model run to + = open and read from bias correction file(s) +!kind=default +type=integer + +#============================================================================== +# IDEALISED CASES +#============================================================================== +[namelist:idealised] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +ns=namelist/Job/Initial conditions + +[!namelist:idealised=f_lon] +compulsory=false +description=Longitude for idealised domain [rad]. +expression=namelist:idealised=f_lon_deg * source:constants_mod=PI / 180.0_r_def +help=Longitude for idealised domain [rad]. + = + =Used in calculations of the solar position. +!kind=default +type=real + +[namelist:idealised=f_lon_deg] +compulsory=true +description=Longitude for idealised domain [degrees]. +fail-if=this < 0.0 ; + =this > 360.0 ; +help=Longitude for idealised domain [degrees]. + = + =Used in calculations of the solar position. +!kind=default +range=0.0:360.0 +sort-key=Panel-A01 +type=real + +[namelist:idealised=perturb_init] +compulsory=true +description=Apply a perturbation to initial conditions of theta sampled from the + =Gaussian distribution and added after hydrostatic balance +help=?????? +!kind=default +sort-key=Panel-A05 +trigger=namelist:idealised=perturb_magnitude: this == ".true."; + =namelist:idealised=perturb_seed: this == ".true."; +type=logical + +[namelist:idealised=perturb_magnitude] +compulsory=true +description=A scaling to be applied to the perturbation by multiplying each + =perturbation by 10**perturb_magnitude +help=?????? +!kind=default +sort-key=Panel-A05 +type=integer + +[namelist:idealised=perturb_seed] +compulsory=true +description=A random seed to be applied in the case that perturb_init is true. + = Should be an integer of size ~10^6. If not supplied then no seed + = will be set and the test will not be repeatable. +help=?????? +!kind=default +sort-key=Panel-A05 +type=integer + +[namelist:idealised=test] +compulsory=true +description=?????? +!enumeration=true +fail-if=this == "'yz_cosine_hill'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'cold_bubble_x'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'cold_bubble_y'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'warm_bubble'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'warm_bubble_3d'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'hadley_like_dcmip'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'vortex_field'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'deep_baroclinic_wave'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'solid_body_rotation'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'solid_body_rotation_alt'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'cos_phi'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'cosine_bell'" and namelist:base_mesh=geometry == "'planar'" ; + =this == "'cosine_bubble'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'eternal_fountain'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'curl_free_reversible'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'div_free_reversible'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'translational'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'rotational'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'vertical_cylinder'" and namelist:base_mesh=geometry == "'spherical'" ; + =this == "'bryan_fritsch'" and namelist:base_mesh=geometry == "'spherical'"; + =this == "'grabowski_clark'" and namelist:base_mesh=geometry == "'spherical'"; + =this == "'grabowski_clark'" and namelist:formulation=moisture_formulation == "'dry'"; +help=gravity_wave : Gravity wave test (planar|spherical) + =isot_atm : Isothermal atmosphere + =isot_cold_atm : Isothermal atmosphere, cold ground temperature + =isot_dry_atm : Isothermal and dry atmosphere + =cold_bubble_x : Straka density cold current test in x direction (planar) + =cold_bubble_y : Straka density cold current test in y direction (planar) + =const_lapse_rate : const_lapse_rate : Stratified atmosphere, constant lapse rate + =warm_bubble : Warm bubble test (planar) + =warm_bubble_3d : 3d Warm bubble test (planar) + =gaussian_hill : Pair of Gaussian hills (planar|spherical) + =cosine_hill : Pair of cosine hills (planar|spherical) + =cosine_bell : Pair of 3D cosine bells (spherical) + =yz_cosine_hill : Pair of cosine hills (in a y-z slice of the planar domain) + =slotted_cylinder : Pair of slotted cylinders (planar|spherical) + =constant_field : Constant density value everywhere (planar|spherical) + =cosine_stripe : Cosine profile which is a function of longitude only (planar|spherical) + =vortex_field : Pair of vortices (spherical) + =hadley_like_dcmip : Hadley-like DCMIP test (spherical) + =solid_body_rotation : Solid body rotation test + =solid_body_rotation_alt : Switchable deep/shallow solid body rotation test + =deep_baroclinic_wave : Deep atmosphere baroclinic wave (Ullrich 13) + =isentropic : Stationary isentropic case + =cos_phi : Advection of latitudinally varying function + =cosine_bubble : Advection of a cosine bubble in an x-z domain + =eternal_fountain : A mimic of an eternal fountain + =curl_free_reversible : A curl-free reversible flow with high divergence + =div_free_reversible : A divergence-free deformative flow + =translational : Simple translational flow + =rotational : A vertical solid body rotation + =vertical_cylinder : A cylinder for a vertical slice + =specified_profiles : Use profile data provided by initial namelists + =bryan_fritsch : Rising bubble test of Bryan and Fritsch (2002) + =grabowski_clark : Rising bubble test of Grabowski and Clark (1991) +sort-key=Panel-A01 +trigger=namelist:initial_temperature=profile_data: 'specified_profiles'; + =namelist:initial_temperature=profile_heights: 'specified_profiles'; + =namelist:initial_temperature=profile_size: 'specified_profiles'; + =namelist:initial_vapour=profile_data: 'specified_profiles'; + =namelist:initial_vapour=profile_heights: 'specified_profiles'; + =namelist:initial_vapour=profile_size: 'specified_profiles'; +value-titles=None, Gravity Wave, Isothermal atmosphere, Cold ground temperature, + =Isothermal dry atmosphere, Cold bubble x, + =Cold bubble y, Constant lapse rate, Warm bubble, Warm bubble 3d, Gaussian hill, + =Cosine hill, Cosine bell 3D, YZ cosine hill, Slotted cylinder, Constant field, + =Cosine stripe, Hadley like DCMIP, Vortex field, Solid body rotation, + =Solid body rotation alt, Deep baroclinic wave, Isentropic, + =Advection of cos(phi) function, Advection of a cosine bubble, + =Eternal fountain, A reversible potential flow, A deformative twisting flow, + =Uniform translation, Vertical solid body rotation, Cylinder for vertical slice, + =Specified profiles, Bryan and Fritsch (2002) rising bubble, + =Grabowski and Clark (1991) moist rising bubble in an unsaturated atmosphere +# initial temp namelists +# XS +# trigger=namelist:initial_density: 'none' ; +# namelist:initial_temperature: 'none' ; +# namelist:initial_wind: 'none' ; +values='none', 'gravity_wave', 'isot_atm', 'isot_cold_atm', 'isot_dry_atm', 'cold_bubble_x', + ='cold_bubble_y', 'const_lapse_rate', 'warm_bubble', 'warm_bubble_3d', 'gaussian_hill', + ='cosine_hill', 'cosine_bell', 'yz_cosine_hill', 'slotted_cylinder', 'constant_field', 'cosine_stripe', + ='hadley_like_dcmip', 'vortex_field', 'solid_body_rotation', + ='solid_body_rotation_alt', 'deep_baroclinic_wave', 'isentropic', + ='cos_phi','cosine_bubble', + ='eternal_fountain', 'curl_free_reversible', 'div_free_reversible', 'translational', + ='rotational','vertical_cylinder', 'specified_profiles', 'bryan_fritsch', 'grabowski_clark' + +#============================================================================== +# INITIAL DENSITY +#============================================================================== +[namelist:initial_density] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +ns=namelist/Job/Initial conditions/Density +sort-key=Section-A03 + +[namelist:initial_density=density_background] +compulsory=true +description=?????? +fail-if=this < 0.0 ; +help=Background value of initial idealised density +!kind=default +range=0.0: +sort-key=Panel-A03 +# This variable is only valid for the following idealised test cases: cosine_hill, yz_cosine_hill, +# slotted_cylinder, cosine_stripe, constant_field +type=real + +[namelist:initial_density=density_max] +compulsory=true +description=?????? +fail-if=this < 0.0 ; +help=Maximum value of initial idealised density +!kind=default +range=0.0: +sort-key=Panel-A02 +# trigger= only valid for some of idealised test cases namelist:idelaised=test Add comments as to which +# This variable is only valid for the following idealised test cases: gaussian_hill, cosine_hill, +# yz_cosine_hill, slotted_cylinder, cosine_stripe, +type=real + +[namelist:initial_density=r1] +compulsory=true +description=?????? +# fail-if= only valid for certain tests +fail-if=this < 0.0 ; +# Poor, variables should not change units based on other settings!! +help=Radius for one of the pair of initial tracer functions + =Biperiodic domain: in metres. + =Cubed sphere domain: in radians. +!kind=default +range=0.0: +#range= +sort-key=Panel-A04 +type=real + +[namelist:initial_density=r2] +compulsory=true +description=?????? +fail-if= +help=Radius parameter for the second of the pair of initial tracer functions (see r1) +!kind=default +!range= +sort-key=Panel-A08 +trigger= +type=real + +[namelist:initial_density=x1] +compulsory=true +description=?????? +# trigger= only valid for some of idealised test cases namelist:idelaised=test Add comments as to which +# A change in the way it is coded is needed as x1 is required for several of the idealised tests but need +# not be. +# Poor, variables should not change units based on other settings!! +help=Position for one of the pair of initial tracer functions + =Biperiodic domain: centre of the function given in terms of metres in the chi1 direction. + =Cubed sphere domain: longitudinal position of the centre of the function (a value between 0 and \f$2\pi\f$). +!kind=default +#range= +sort-key=Panel-A05 +trigger= +type=real + +[namelist:initial_density=x2] +compulsory=true +description=?????? +fail-if= +help=Position parameter for the second of the pair of initial tracer functions (see x1) +!kind=default +!range= +sort-key=Panel-A09 +trigger= +type=real + +[namelist:initial_density=y1] +compulsory=true +description=?????? +fail-if= +# A change in the way it is coded is needed as y1 is required for several of the idealised tests but need +# not be. +# Poor, variables should not change units based on other settings!! +help=Position for one of the pair of initial tracer functions + =Biperiodic domain: centre of the function given in terms of metres in the chi2 direction. + =Cubed sphere domain: latitudinal position of the centre of the function (a value between \f$-\pi/2\f$ and \f$\pi/2\f$). +!kind=default +!range= +sort-key=Panel-A06 +trigger= +type=real + +[namelist:initial_density=y2] +compulsory=true +description=?????? +fail-if= +help=Position parameter for the second of the pair of initial tracer functions (see y1) +!kind=default +!range= +sort-key=Panel-A10 +trigger= +type=real + +[namelist:initial_density=z1] +compulsory=true +description=?????? +fail-if= +help=Centre height position for one of the pair of initial tracer functions +!kind=default +!range= +sort-key=Panel-A07 +trigger= +# Only valid for yz_cosine_hill +type=real + +[namelist:initial_density=z2] +compulsory=true +description=?????? +fail-if= +help=Centre height position for one of the pair of initial tracer functions +!kind=default +!range= +sort-key=Panel-A11 +# Only valid for yz_cosine_hill +trigger= +type=real + +#============================================================================== +# INITIAL PRESSURE +#============================================================================== +[namelist:initial_pressure] +compulsory=true +description=Options for initialising Exner +help= +!kind=default +ns=namelist/Job/Initial conditions/Pressure +sort-key=Section-A02 + +[namelist:initial_pressure=method] +compulsory=true +description=Method used to initialise Exner +!enumeration=true +help=Three methods are available for idealised initialisation of Exner pressure: + ='sampled' - analytic function sampled at finite element data points + ='projected' - analytic function projected onto finite element representation + ='balanced' - Exner calculated using discrete hydrostatic balance + = (only works for element_order_h=0 and element_order_v=0 + = until #2304 is implemented) +sort-key=Panel-A01 +value-titles=None, Sampled at data points, Projected onto elements, Discrete hydrostatic balance +values='none', 'sampled', 'projected', 'balanced' + +[namelist:initial_pressure=surface_pressure] +compulsory=true +description=Pressure at sea level (Pa) +help=Pressure in Pascals at the lower boundary. When orography is present, + =this is taken to be pressure at sea level. +!kind=default +sort-key=Panel-A02 +type=real + +#============================================================================== +# INITIAL TEMPERATURE +#============================================================================== +[namelist:initial_temperature] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +ns=namelist/Job/Initial conditions/Temperature +sort-key=Section-A01 + +[namelist:initial_temperature=bvf_square] +compulsory=true +description=?????? +help=The square of Brunt-Vaisala frequency [1/s^2] +!kind=default +sort-key=Panel-A01 +type=real + +[namelist:initial_temperature=pert_centre] +compulsory=true +description=Centre (in degrees) of the temperature perturbation. +fail-if=this < -180.0 ; + =this > 180.0 ; +help=For the Gravity wave idealised case set the location (in longitude) of the + =initial pertubation +!kind=default +sort-key=Panel-A05 +type=real + +[namelist:initial_temperature=pert_width_scaling] +compulsory=true +description=The scaling applied to the temperature perturbation width. +help=This is designed to allow a smaller perturbation width to be used for a + =limited area model on one panel, and zero flux LBCs. +!kind=default +sort-key=Panel-A03b +type=real +warn-if=this <= 0.0 ; + +[namelist:initial_temperature=perturb] +compulsory=true +description=Add a perturbation to the initial potential temperature +!enumeration=true +help=random - random noise (same on each processor) +sort-key=Panel-A03 +value-titles=None, Random +values='none', 'random' + +[namelist:initial_temperature=profile_data] +!bounds=namelist:initial_temperature=profile_size +compulsory=true +description=Initial temperature profile +help=Values of potential temperature (Kelvin) at heights specified in profile_heights. +!kind=default +length=: +range=0.0: +sort-key=Panel-A04b +type=real + +[namelist:initial_temperature=profile_heights] +!bounds=namelist:initial_temperature=profile_size +compulsory=true +description=Heights for temperature profile +help=Heights, in metres, at which temperature data are specified. +!kind=default +length=: +range=0.0: +sort-key=Panel-A04c +type=real + +[namelist:initial_temperature=profile_size] +compulsory=true +description=Size of initial profile +help=Number of data points in the initial profile. +!kind=default +range=0:200 +sort-key=Panel-A04a +type=integer + +[namelist:initial_temperature=theta_surf] +compulsory=true +description=?????? +help=Value of temperature at z=0 +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real +warn-if=this <= 0.0 ; + +#============================================================================== +[namelist:initial_vapour] +compulsory=true +description=Initialisation of the water vapour field +help=Options for idealised initialisation of water vapour +!kind=default +ns=namelist/Job/Initial conditions/Vapour +sort-key=Section-A03 + +[namelist:initial_vapour=profile_data] +!bounds=namelist:initial_vapour=profile_size +compulsory=true +description=Initial vapour profile +help=Values specifying mixing ratio (kg/kg) of water vapour at heights specified + =in profile_heights. +!kind=default +length=: +range=0.0: +sort-key=Panel-A03 +type=real + +[namelist:initial_vapour=profile_heights] +!bounds=namelist:initial_vapour=profile_size +compulsory=true +description=Nodal heights for vapour profile +help=Heights, in metres, of nodes for specifying a vapour profile +!kind=default +length=: +range=0.0: +sort-key=Panel-A04 +type=real + +[namelist:initial_vapour=profile_size] +compulsory=true +description=Number of points in initial vapour profile +help=Number of data points in the initial profile +!kind=default +range=0:200 +sort-key=Panel-A02 +type=integer + +#============================================================================== +[namelist:initial_wind] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +ns=namelist/Job/Initial conditions/Wind +sort-key=Section-A04 + +[namelist:initial_wind=nl_constant] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +sort-key=Panel-A07 +type=real + +[namelist:initial_wind=profile] +compulsory=true +description=Initial wind profiles for GungHo and Transport Miniapp tests. +!enumeration=true +fail-if=this == "'sbr_with_vertical'" and namelist:base_mesh=geometry != "'spherical'" ; + =this == "'dcmip_101'" and namelist:base_mesh=geometry != "'spherical'" ; + =this == "'vertical_deformation'" and namelist:base_mesh=geometry != "'spherical'" ; + =this == "'four_part_sbr'" and namelist:base_mesh=geometry != "'spherical'" ; +help=Select the initial wind profiles for the GungHo and Transport miniapp test cases. + =Solid body rotation with vertical wind: Standard horizontal SBR with a vertical translation. + =DCMIP 2012 Test 1.1: From Kent et al. 2014, it uses the Nair-Lauritzen + =test 4 deformational flow in the horizontal, and a vertical translation. Ony suitable for spherical geometry. + =Vertical Deformational Flow: Uses the Nair-Lauritzen test 4 deformational flow in the + =longitude-height plane. Ony suitable for spherical geometry. +# Add help description of different values +sort-key=Panel-A01 +trigger=namelist:initial_wind=profile_data_u: 'pw_linear'; + =namelist:initial_wind=profile_data_v: 'pw_linear'; + =namelist:initial_wind=profile_data_w: 'pw_linear'; + =namelist:initial_wind=profile_heights_uv: 'pw_linear'; + =namelist:initial_wind=profile_heights_w: 'pw_linear'; + =namelist:initial_wind=profile_size_uv: 'pw_linear'; + =namelist:initial_wind=profile_size_w: 'pw_linear'; +value-titles=None, Solid body rotation, Solid body rotation-alt, Constant uv, Constant shear uv, + =Sin wave uv, DCMIP 3.0.1, Deep baroclinic-steady, Deep baroclinic-perturbed, + =NL case-1, NL case-2, NL case-3, NL case-4, xy NL case-1, yz NL case-1, + =Hadley like DCMIP, Vortex, + =Solid body rotation-Streamfunction, DCMIP 3.0.1-Streamfunction, Eternal fountain, + =Reversible curl free, Reversible divergence free, Vertical solid body rotation, + =Solid body rotation with vertical wind, DCMIP 2012 Test 1.1, Vertical Deformational Flow, + =Solid body rotation around sphere in four parts, + =Piecewise linear vertical profile +# PLEASE add coments to indicate which of these values should allowed given +# the value of namelist:idealised=test +# the value of the mesh geometry +values='none', 'solid_body_rotation', 'solid_body_rotation_alt', 'constant_uv', 'constant_shear_uv', + ='sin_uv','dcmip301', 'deep_baroclinic_steady', 'deep_baroclinic_perturbed', + ='NL_case_1', 'NL_case_2', 'NL_case_3', 'NL_case_4', 'xy_NL_case_1', 'yz_NL_case_1', + ='hadley_like_dcmip', 'vortex', 'sbr_streamfunction', 'dcmip301_streamfunction', 'eternal_fountain', + ='curl_free_reversible', 'div_free_reversible', 'rotational', + ='sbr_with_vertical','dcmip_101', 'vertical_deformation', 'four_part_sbr', 'pw_linear' + +[namelist:initial_wind=profile_data_u] +!bounds=namelist:initial_wind=profile_size_uv +compulsory=true +description=Initial u profile +help=Values specifying u component of wind (m/s) at heights specified + =in profile_heights. Linear interpolation is applied between the + =specified heights. +!kind=default +length=: +sort-key=Panel-A03 +type=real + +[namelist:initial_wind=profile_data_v] +!bounds=namelist:initial_wind=profile_size_uv +compulsory=true +description=Initial v profile +help=Values specifying v component of wind (m/s) at heights specified + =in profile_heights. Linear interpolation is applied between the + =specified heights. +!kind=default +length=: +sort-key=Panel-A03 +type=real + +[namelist:initial_wind=profile_data_w] +!bounds=namelist:initial_wind=profile_size_w +compulsory=true +description=Initial w profile +help=Values specifying w component of wind (m/s) at heights specified + =in profile_heights. Linear interpolation is applied between the + =specified heights. +!kind=default +length=: +sort-key=Panel-A03 +type=real + +[namelist:initial_wind=profile_heights_uv] +!bounds=namelist:initial_wind=profile_size_uv +compulsory=true +description=Nodal heights for profiles of horizontal wind +help=Heights, in metres, of nodes for specifying horizontal wind profiles +!kind=default +length=: +range=0.0: +sort-key=Panel-A04 +type=real + +[namelist:initial_wind=profile_heights_w] +!bounds=namelist:initial_wind=profile_size_w +compulsory=true +description=Nodal heights for profile of vertical wind +help=Heights, in metres, of nodes for specifying vertical wind profile +!kind=default +length=: +range=0.0: +sort-key=Panel-A04 +type=real + +[namelist:initial_wind=profile_size_uv] +compulsory=true +description=Size of horizontal wind profile data +help=Number of data points in the initial profiles for horizontal wind +!kind=default +range=1:200 +sort-key=Panel-A02 +type=integer + +[namelist:initial_wind=profile_size_w] +compulsory=true +description=Size of vertical wind profile data +help=Number of data points in the initial profile for vertical wind +!kind=default +range=1:200 +sort-key=Panel-A02 +type=integer + +[namelist:initial_wind=sbr_angle_lat] +#Units? Degrees radians []?? +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:initial_wind=sbr_angle_lon] +#Units? Degrees radians []?? +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +sort-key=Panel-A05 +type=real + +[namelist:initial_wind=shear] +compulsory=false +description=Shear value used to initialise wind +help=This value is used to initialise constant_shear_uv + =Wind profile is computed using: + =u(z) = u0*z/shear +!kind=default +sort-key=Panel-A09 +type=real + +[namelist:initial_wind=smp_init_wind] +compulsory=true +description=sample initial wind or not. +help=?????? + =?????? +!kind=default +sort-key=Panel-A08 +type=logical + +[namelist:initial_wind=u0] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +sort-key=Panel-A02 +type=real + +[namelist:initial_wind=v0] +compulsory=true +description=?????? +help=?????? + =?????? +!kind=default +sort-key=Panel-A03 +type=real + +[namelist:initial_wind=wavelength] +compulsory=false +description=Wavelength used in sin_uv wind profile +help=Wavelength for sin uv profile + =Wind profile is computed using: + =u(z) = u0*sin(2pi*k_z), where k_z = 2*pi/wavelength +!kind=default +sort-key=Panel-A10 +type=real + +[namelist:initial_wind=wind_time_period] +compulsory=true +description=?????? +fail-if=this < 0.0 ; +help=?????? + =?????? +!kind=default +range=0.0: +sort-key=Panel-A06 +type=real + +#============================================================================== +# Field Initialization +#============================================================================== +[namelist:initialization] +compulsory=true +description=Sets up options for field initialization +help=?????? + =?????? +ns=namelist/Job/IO/Field Initialisation +sort-key=sec-AAAA + +[namelist:initialization=ancil_option] +compulsory=true +description=Where from and how to process ancillary data +!enumeration=true +help=start_dump will process some ancillary information from the start dump. + = This is useful for aquaplanet runs. + = + =fixed will read the ancillary files and interpolate the data to the + = start date of the model, holding it fixed after this. + = This is typically how forecast runs are done. + = + =updating is as fixed, but will additionally update the ancillary data + = as the run progresses. + = This is typically how climate runs are done. +sort-key=01 +trigger=namelist:files=land_area_ancil_path: 'fixed', 'updating' ; + =namelist:files=orography_subgrid_ancil_path: 'fixed', 'updating' ; + =namelist:files=soil_ancil_path: 'fixed', 'updating' ; + =namelist:files=soil_rough_ancil_path: 'fixed', 'updating' ; + =namelist:files=aerosols_ancil_path: 'fixed', 'updating' ; + =namelist:files=plant_func_ancil_path: 'fixed', 'updating' ; + =namelist:files=sea_ancil_path: 'fixed', 'updating' ; + =namelist:files=sst_ancil_path: 'fixed', 'updating' ; + =namelist:files=snow_analysis_ancil_path: 'fixed', 'updating' ; + =namelist:files=sea_ice_ancil_path: 'fixed', 'updating' ; + =namelist:files=albedo_vis_ancil_path: 'fixed', 'updating' ; + =namelist:files=albedo_nir_ancil_path: 'fixed', 'updating' ; + =namelist:files=hydtop_ancil_path: 'fixed', 'updating' ; + =namelist:files=ozone_ancil_path: 'fixed', 'updating' ; + =namelist:files=surface_frac_ancil_path: 'fixed', 'updating' ; + =namelist:files=urban_ancil_path: 'fixed', 'updating' ; + =namelist:files=emiss_bc_biofuel_ancil_path: 'updating' ; + =namelist:files=emiss_bc_fossil_ancil_path: 'updating' ; + =namelist:files=emiss_bc_biomass_ancil_path: 'updating' ; + =namelist:files=emiss_bc_biomass_hi_ancil_path: 'updating' ; + =namelist:files=emiss_bc_biomass_lo_ancil_path: 'updating' ; + =namelist:files=emiss_c2h6_ancil_path: 'updating' ; + =namelist:files=emiss_c3h8_ancil_path: 'updating' ; + =namelist:files=emiss_c5h8_ancil_path: 'updating' ; + =namelist:files=emiss_ch4_ancil_path: 'updating' ; + =namelist:files=emiss_co_ancil_path: 'updating' ; + =namelist:files=emiss_dms_land_ancil_path: 'updating' ; + =namelist:files=dms_conc_ocean_ancil_path: 'updating' ; + =namelist:files=emiss_hcho_ancil_path: 'updating' ; + =namelist:files=emiss_me2co_ancil_path: 'updating' ; + =namelist:files=emiss_mecho_ancil_path: 'updating' ; + =namelist:files=emiss_meoh_ancil_path: 'updating' ; + =namelist:files=emiss_monoterp_ancil_path: 'updating' ; + =namelist:files=emiss_nh3_ancil_path: 'updating' ; + =namelist:files=emiss_no_ancil_path: 'updating' ; + =namelist:files=emiss_no_aircrft_ancil_path: 'updating' ; + =namelist:files=emiss_om_biofuel_ancil_path: 'updating' ; + =namelist:files=emiss_om_fossil_ancil_path: 'updating' ; + =namelist:files=emiss_om_biomass_ancil_path: 'updating' ; + =namelist:files=emiss_om_biomass_hi_ancil_path: 'updating' ; + =namelist:files=emiss_om_biomass_lo_ancil_path: 'updating' ; + =namelist:files=emiss_so2_low_ancil_path: 'updating' ; + =namelist:files=emiss_so2_high_ancil_path: 'updating' ; + =namelist:files=emiss_so2_nat_ancil_path: 'updating' ; + =namelist:files=h2o2_limit_ancil_path: 'updating' ; + =namelist:files=ho2_ancil_path: 'updating' ; + =namelist:files=no3_ancil_path: 'updating' ; + =namelist:files=o3_ancil_path: 'updating' ; + =namelist:files=oh_ancil_path: 'updating' ; + =namelist:files=soil_dust_ancil_path: 'fixed', 'updating' ; + =namelist:files=emiss_murk_ancil_path: 'fixed', 'updating' ; + =namelist:initialization=sst_source: 'fixed' ; + =namelist:files=ea_ancil_directory: 'updating' ; + =namelist:files=cloud_drop_no_conc_ancil_path: 'updating' ; + =namelist:files=easy_absorption_sw_ancil_path: 'updating' ; + =namelist:files=easy_extinction_sw_ancil_path: 'updating' ; + =namelist:files=easy_asymmetry_sw_ancil_path: 'updating' ; + =namelist:files=easy_absorption_lw_ancil_path: 'updating' ; + =namelist:files=easy_extinction_lw_ancil_path: 'updating' ; + =namelist:files=easy_asymmetry_lw_ancil_path: 'updating' ; + =namelist:files=gas_mmr_ancil_path: 'idealised' ; +values='none', 'start_dump', 'fixed', 'updating', 'idealised' + +[namelist:initialization=coarse_aerosol_ancil] +compulsory=true +description=Whether to read in aerosol ancil on coarse mesh +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A12a +trigger=namelist:files=coarse_ancil_directory: .true. +type=logical + +[namelist:initialization=coarse_orography_ancil] +compulsory=true +description=Whether to read in orography on coarse mesh +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A13 +trigger= +type=logical + +[namelist:initialization=coarse_ozone_ancil] +compulsory=true +description=Whether to read in ozone ancil on coarse mesh +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A12b +trigger=namelist:files=coarse_ancil_directory: .true. +type=logical + +[namelist:initialization=init_option] +compulsory=true +description=Choice for initialization of model fields +!enumeration=true +!fail-if=this='checkpoint_dump' and namelist:io=checkpoint_read==.false. +help=Choose how to initialize the model fields: + = 'analytic' : Initialization is taken from analytic fields. See + = the appropriate related namelists for choices available. + = 'checkpoint_dump' : Initialize the model from a checkpoint from a previous + =lfric run. + = 'fd_start_dump' : Initialize fields from a start dump file on disk. + =The data in this file will be used to populate finite + =difference fields, i.e. physics fields from which the + =model will run. + = 'fe_start_dump' : Initialize fields from a start dump file on disk. The + =data in this file will be used to populate finite element + =fields, i.e. gungho dynamics fields from which the model + =will run. NOT CURRENTLY IMPLEMENTED +sort-key=02 +trigger=namelist:initialization=model_eos_height: 'fd_start_dump', 'fe_start_dump' +values='analytic', 'checkpoint_dump', 'fd_start_dump', 'fe_start_dump' + +[namelist:initialization=lbc_option] +compulsory=true +description=Choice of which lateral boundary conditions to read in. +!enumeration=true +fail-if=this=='gungho_file' and namelist:boundaries=limited_area !="'.true.'" ; + =this=='um2lfric_file' and namelist:boundaries=limited_area !="'.true.'" ; + =this=='analytic' and namelist:boundaries=limited_area !="'.true.'" +help=Currently support is only available for: + ='none', 'analytic','gungho_file', 'um2lfric_file' +sort-key=03 +trigger=namelist:files=lbc_directory: 'file', 'gungho_file', 'um2lfric_file'; + =namelist:files=lbc_filename: 'gungho_file', 'um2lfric_file' ; +values='none', 'analytic', 'gungho_file', 'um2lfric_file' + +[namelist:initialization=ls_option] +compulsory=true +description=Choice of which linearisation state. +!enumeration=true +help=Currently support is only available for: + ='none', 'analytic','file' +sort-key=04 +trigger=namelist:files=ls_directory: 'file' ; + =namelist:files=ls_filename: 'file' ; +values='none', 'analytic', 'file' + +[namelist:initialization=model_eos_height] +compulsory=true +!default=kind +description=Exner initialisation height for the initial conditions [%]. +help=The value is an integer percentage of the atmospheric depth before any application of orography. + =It is used to determine the atmospheric layer/level at which to begin Exner profile initialisation + =for the initial conditions. The Equation of State (EoS) is satisfied at the resulting layer + =where Exner initialisation begins. + = + =To initialise an Exner vertical profile, the Equation of state (EoS) is first used + =to calculate Exner on a single vertical layer L using density and temperature. + =This vertical layer L is the nearest layer to (model_eos_height/100)*total_height. + =Then hydrostatic balance is used to integrate from this layer to the top of the atmosphere, + =and similarly to the bottom of the atmosphere. + = + =If model_eos_height=0, the initial layer is 1 so the EoS is solved for the bottom layer + =and then hydrostatic balance is used to integrate upwards to the top of the model. + =If model_eos_height=100, the initial layer is number_of_layers, so the EoS is solved for the + =top layer, and then hydrostatic balance is used to integrate downwards to the bottom of the model. + = + =It is also possible to use any value between 0 and 100, so that hydrostatic balance is + =used to integrate both upwards and downwards. +range=0:100 +sort-key=02a +type=integer + +[namelist:initialization=n_orog_smooth] +compulsory=true +description=Number of passes of a 1-2-1 smoothing filter applied to the orography. +fail-if=this != "0" and namelist:boundaries=limited_area =="'.false.'" ; +help=Smoothing is only available to limited area (lat/lon non-periodic mesh) models. +!kind=default +range=0: +sort-key=Panel-A07 +type=integer + +[namelist:initialization=read_w2h_wind] +compulsory=true +!default=kind +description=Horizontal winds are read in on a W2h space from a start dump. If + = false, then cell-centres (W3), co-located winds are assumed. +help=Horizontal winds are read in on a W2h space from a start dump. If + = false, then cell-centres (W3), co-located winds are assumed. +sort-key=02b +type=logical + +[namelist:initialization=sea_ice_source] +compulsory=true +description=Where to read the sea ice fields from +!enumeration=true +help=The sea ice fraction (and thickness if amip_ice_thick is false) can either be read from an static ancillary file + = (typical in climate runs or NWP forecasts using an analysis file), or from a SURF derived ancillary file + = To use a SURF produced ancillary-style file, select `surf` else just `ancillary` + = + =The iodef file must be consistent with this setting, specifying + = seaice from either a static ancillary file or a SURF-derived ancillary file. +sort-key=01a +values='ancillary', 'surf' + +[namelist:initialization=snow_source] +compulsory=true +description=Where to read the snow fields from +!enumeration=true +help=The snow fields can be read either from the start dump, or from an ancillary, for example SURF analysis. + =To use the start_dump select `start_dump` else `surf` for SURF snow analysis. + = + =The iodef file must be consistent with this setting, specifying the snow fields in their own ancillary file. +sort-key=01c +trigger=namelist:files=snow_analysis_ancil_path: 'surf'; +values='start_dump','surf' + +[namelist:initialization=sst_source] +compulsory=true +description=Where to read the sea-surface temperature from +!enumeration=true +help=The sea-surface temperature can either be read from an ancillary file + = (typical in climate runs or NWP forecasts using an analysis file), + = or from the start dump (typical for downscaling models). + = To use a SURF produced ancillary-style file, select `surf` else just `ancillary` + = + =The iodef file must be consistent with this setting, specifying + = tstar_sea from either type of ancillary file or as part of the start dump. +sort-key=01b +values='ancillary','start_dump','surf' + +[namelist:initialization=w0_orography_mapping] +compulsory=true +description=Whether to map orography between meshes using W0 mapping rather than W3 +help= +!kind=default +ns=namelist/Science/Dynamics +sort-key=Panel-A14 +type=logical + +[namelist:initialization=zero_w2v_wind] +compulsory=true +description=Zero vertical DoFs of initial wind field +help=If true then zero the vertical DoFs of the initial wind field +!kind=default +sort-key=02c +type=logical + +#============================================================================== +# IO +#============================================================================== +[namelist:io=diag_active_files] +compulsory=true +description=List of IDs of active diagnostics output files for use in dynamic sampling. +fail-if= +help=Include the ID of any active diagnostics file in this list. +length=: +ns=namelist/Job/IO/Diagnostics +sort-key=Panel-A05 +!string_length=filename +trigger= +type=character + +[namelist:io=diag_always_on_sampling] +compulsory=true +description=Force field sampling status to always true for backwards compatibility and for testing. + =Setting it to false is an optimisation and will not affect the production of diagnostics. +fail-if= +help=Set to true for backwards compatible diagnostics and for testing dynamic sampling. +ns=namelist/Job/IO/Diagnostics +sort-key=Panel-A05 +trigger= +type=logical + +[namelist:io=multifile_io] +compulsory=true +description=Use multifile IO functionality +!kind=default +ns=namelist/Job/IO/Diagnostics +sort-key=Panel-A05 +type=logical + +[namelist:io=write_conservation_diag] +compulsory=true +description=Enable write of conservation diagnostics for masses, energy and axial ang. mom. +help=Writes out conservation diagnostics to the job log. These are the totals of + =dry mass, energy and axial angular momentum. In the presence of moisture, + =the total mass of each species of moisture is also written out as well as + =the masses of water associated with fluxes from precipitation and the boundary layer. +!kind=default +ns=namelist/Job/IO/Diagnostics +sort-key=Panel-A05 +type=logical + +[namelist:io=write_diag] +trigger=namelist:io=diagnostic_frequency: .true. ; + =namelist:io=nodal_output_on_w3: .true. ; + =namelist:io=write_minmax_tseries: .true. ; + =namelist:files=diag_stem_name: .true. ; + +[namelist:io=write_dump] +compulsory=true +description=Enable dump of a field +help=Write a dump of a field +!kind=default +ns=namelist/Job/IO/Dumping +sort-key=A-001 +type=logical + +[namelist:io=write_fluxes] +compulsory=true +description=Write out fluxes for vector fields +help=In addition to outputting u1,u2 and u3, output fluxes on w2h and wtheta +!kind=default +ns=namelist/Job/IO/Diagnostics +sort-key=Panel-A04 +type=logical + +[namelist:io=write_minmax_tseries] +compulsory=true +description=Enable write of maxima and minima + =of fields for time-series. +help=Writes out a min/max of fields to text file +!kind=default +ns=namelist/Job/IO/Diagnostics +sort-key=Panel-A05 +type=logical + +#============================================================================== +# OUTER SOLVER +#============================================================================== +[namelist:mixed_solver] +compulsory=true +description=?????? +help=This namelist is for the mixed (outer) si solver +ns=namelist/Science/Dynamics/mixed_solver +sort-key=Section-A07 +title=Outer solver + +[namelist:mixed_solver=eliminate_variables] +compulsory=true +description=Eliminate the density and potential temperature from the mixed solver. +!enumeration=true +help=Eliminate the density and potential temperature from the mixed solver using + =either discrete or analytic elimination. See solver documentation of + =https://code.metoffice.gov.uk/trac/lfric/wiki/GhaspSupport/Documentation + =for further details. +!kind=default +sort-key=Panel-A07 +value-titles=Discrete, Analytic +values='discrete', 'analytic' + +[namelist:mixed_solver=fail_on_non_converged] +compulsory=true +description=Cause the solver to return an error if the maximum number of iterations are reached and + =residual has not been reduced below the desired tolerance otherwise the solver will exit even + =if it has not converged. If monitor_convergence is set to false then this setting has no effect +help=Return an error if solver fails to converge +sort-key=Panel-A07 +type=logical + +[namelist:mixed_solver=gcrk] +compulsory=true +description=?????? +help=Dimension of the approximate Krylov subspace. + =In other words, it is the number of potential + =residual vectors to calculate at each + =iteration of the solver. +!kind=default +sort-key=Panel-A05 +type=integer + +[namelist:mixed_solver=guess_np1] +compulsory=true +description=?????? +help=Guess values for theta, rho and exner n+1 in inner loop +!kind=default +sort-key=Panel-A06 +type=logical + +[namelist:mixed_solver=jacobi_relaxation] +compulsory=true +description=?????? +help=Relaxtion factor to use in the Jacobi solver +!kind=default +sort-key=Panel-A11 +type=real + +[namelist:mixed_solver=mixed_solver_a_tol] +compulsory=true +description=Sets the absolute tolerance of semi-implicit solver. +help=Absolute tolerance of semi-implicit solver + =Safe value is (\f$10^{-6}\f$), but optimal value may depend + =on model configuration. +!kind=default +range=0:1 +sort-key=Panel-A02 +type=real + +[namelist:mixed_solver=monitor_convergence] +compulsory=true +description=Computes and prints out convergence information for the iterative solver and if the + =error has been reduced below the tolerance then the solver will exit. If set to false + =the solver will always perform the maximum number of iterations before exiting +help=Monitor convergence of the iterative mixed solver +sort-key=Panel-A06 +trigger=namelist:mixed_solver=fail_on_non_converged: .true.; +type=logical + +[namelist:mixed_solver=normalise] +compulsory=true +description=?????? +help=Normalise matrix so diagonal is 1 +!kind=default +sort-key=Panel-A08 +type=logical + +[namelist:mixed_solver=reference_reset_time] +compulsory=true +description=The elapsed time (in seconds) between computations of the semi-implicit operators + =for the mixed solve with an updated reference state.This reset time is then divided + =by the timestep and rounded to the nearest integer to determine if the operators + =need to be recomputed. +help=Time passed (in seconds) to reset reference state +!kind=default +sort-key=Panel-A07 +type=real + +[namelist:mixed_solver=si_maximum_iterations] +compulsory=true +description=?????? +fail-if=this < 1 ; +help=Iteration limit for si solver +!kind=default +range=1: +sort-key=Panel-A04 +type=integer + +[namelist:mixed_solver=si_method] +compulsory=true +description=?????? +!enumeration=true +help=?????? + =?????? +!kind=default +sort-key=Panel-A01 +trigger=namelist:mixed_solver=jacobi_relaxation: this == "'jacobi'"; +value-titles=biconjugate gradient stabilized, + =conjugate gradient, + =generalized conjugate residual, + =generalized conjugate residual(block form), + =generalized minimal residual, + =flexible generalized minimal residual, + =precondition only, + =jacobi +values='bicgstab', 'cg', 'gcr', 'block_gcr', 'gmres', 'fgmres', 'prec_only', 'jacobi' + +[namelist:mixed_solver=si_preconditioner] +compulsory=true +description=?????? +!enumeration=true +help=?????? + =?????? +!kind=default +sort-key=Panel-A03 +value-titles=None, Diagonal, Pressure +values='none', 'diagonal', 'pressure' + +[namelist:mixed_solver=si_tolerance] +compulsory=true +description=?????? +help=Relative tolerance of semi-implicit solver +!kind=default +sort-key=Panel-A02 +type=real + +[namelist:mixed_solver=split_w] +compulsory=true +description=Split vertical and horizontal components of velocity field in solve +help=??? +!kind=default +sort-key=Panel-A06 +type=logical + +[namelist:mixing] +compulsory=true +description=Subgrid mixing scheme options +help=Currently available schemes are: + =_________________________________________________________________ + =Constant viscosity: + = applied to theta & u, v, w + =_________________________________________________________________ + =Smagorinsky mixing scheme: + = applied to theta, moisture (water vapour and cloud liquid), + = u, v and w + =_________________________________________________________________ + =Vertical Leonard terms: + = turbulent vertical fluxes due to the Leonard terms + = calculated for liquid water temperature, total water content, + = u, v and w + = This scheme can be used with the Smagorinsky mixing scheme + = +!kind=default +ns=namelist/Science/Dynamics/Mixing +sort-key=Section-A05 + +[namelist:mixing=leonard_kl] +compulsory=true +description=Leonard term parameter +help=Scales the Leonard term fluxes applied to winds and scalars. + = A value of 1.0 yields just the Leonard term. + = + = Values in the range 1-6 are justified, as Moeng et al (2010) + = found that a significant fraction of other turbulent flux terms are + = highly correlated with the Leonard term. +!kind=default +sort-key=Panel-A07 +type=real + +[namelist:mixing=leonard_term] +compulsory=true +description=Enable vertical Leonard terms +help=Calculate turbulent vertical fluxes due to Leonard terms, + = as described in Moeng et al (2010). + = + = Fluxes are calculated for: + = Liquid water temperature + = Total water content + = u, v and w + = +!kind=default +sort-key=Panel-A06 +trigger=namelist:mixing=leonard_kl: .true. ; +type=logical + +[namelist:mixing=method] +compulsory=true +description=Smagorinsky subgrid mixing scheme option +!enumeration=true +help=Options for Smagorinsky subgrid mixing scheme: + =_________________________________________________________________ + =3D Smag + = Smagorinsky mixing scheme applied in horizontal and vertical. + =_________________________________________________________________ + =2D Smag + 1D BL + = Smagorinsky mixing scheme applied in horizontal. + = 1D BL scheme used in the vertical. + =_________________________________________________________________ + =Blended scheme + Smag above + = Blended BL-Smagorinsky diffusion coefficient used for + = subgrid mixing in horizontal and vertical. + = Relaxes to 3D Smagorinsky above BL + =_________________________________________________________________ + =Blended scheme + 1D BL above + = As above, but relaxes to 1D BL above BL + = + = WARNING: This option currently does not conserve energy and as + = a result may be unstable. +sort-key=Panel-A05 +value-titles=3D Smagorinsky, 2D Smagorinsky + 1D BL, Blended scheme + Smag above, Blended scheme + 1D BL above +values='3d_smag', '2d_smag', 'blend_smag_fa','blend_1dbl_fa' + +[namelist:mixing=mix_factor] +compulsory=true +description=Smagorinsky mixing length constant +help=Smagorinsky mixing length constant, typical value is 0.2 +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:mixing=smag_l_calc] +compulsory=true +description=Choice of Smagorinsky mixing length calculation +!enumeration=true +help=Option within the Smagorinsky subgrid mixing scheme to use either + =Dx (the mininum of the cell horizontal edge lengths) as the length + =scale or a 3d geometric mean, L=(Dx*Dx*Dz)^1/3 +sort-key=Panel-A05 +value-titles=Use Dx, Use 3D geometric mean +values='UseDx','use_geo' + +[namelist:mixing=smagorinsky] +compulsory=true +description=Enable Smagorinsky mixing +help=Apply Smagorinsky mixing to theta, + = moisture (water vapour and cloud liquid), u, v and w + = + = NOTE: As in the current UM implementation of Smagorinsky mixing, + = the stress terms have been implemented purely as diffusion terms. + = This results in a missing term, as described in UMDP28. + = + = WARNING: Current implementation assumes a Cartesian mesh. +!kind=default +sort-key=Panel-A03 +trigger=namelist:mixing=method: .true. ; + =namelist:mixing=mix_factor: .true. ; + =namelist:mixing=smag_l_calc: .true. ; + =namelist:physics=smagorinsky_placement: .true. ; +type=logical + +#============================================================================== +# MIXING: Namelist Members +#============================================================================== +[namelist:mixing=viscosity] +compulsory=true +description=?????? +help=Apply constant viscosity to theta & u, v, w +!kind=default +sort-key=Panel-A01 +type=logical + +[namelist:mixing=viscosity_mu] +compulsory=true +description=?????? +help=Viscosity constant to use +!kind=default +sort-key=Panel-A02 +type=real + +#============================================================================== +# MULTIRESOLUTION COUPLING (e.g. Physics-Dynamics-Chemistry) +#============================================================================== +[namelist:multires_coupling] +compulsory=false +description=This namelist specifies options for running different model + =components on different meshes +help=This namelist provides different modes and meshes for running the coupling + =miniapp +ns=namelist/Science/Dynamics/multires_coupling +sort-key=Section-A07 +title=Multires-Coupling + +[namelist:multires_coupling=aerosol_mesh_name] +compulsory=false +description=Name of the mesh used for reading in aerosol data. May also be used + =for transporting aerosols. +help=Aerosols are read in (and possibly transported) on this mesh +sort-key=Panel-A03 +!string_length=default +type=character + +[namelist:multires_coupling=coarse_aerosol_transport] +compulsory=false +description=Whether to transport aerosols on the aerosol mesh +help=If this is set to true, aerosols will be transported on the coarse aerosol + =mesh. Otherwise they will be transported on the dynamics mesh. +!kind=default +sort-key=Section-A03b +type=logical + +[namelist:multires_coupling=coarse_rad_aerosol] +compulsory=true +description=Whether to run RADAER, the Jones CDNC calculation, and the + =stratospheric aerosol climatology on a coarse mesh. Resolution of the + =mesh is that of aerosol_mesh_name +help= +!kind=default +sort-key=Section-A08 +type=logical + +[namelist:multires_coupling=dynamics_mesh_name] +compulsory=false +description=Tag-name for mesh used by dynamics +help=This is the mesh on which the dynamical core is run +sort-key=Panel-A02 +!string_length=default +type=character + +[namelist:multires_coupling=lowest_order_aero_flag] +compulsory=false +description=Forces the mapping of aerosol related fields to be lowest order, even if + =recovery_order is set to linear. +help=If this is set to true, aerosols will be mapped using low order mapping. + =If recovery_order is constant and this is set to false, the mapping will still be + =lowest order. But if recovery_order is linear and this is false, the mapping will + =be linear +!kind=default +sort-key=Section-A06b +type=logical + +[namelist:multires_coupling=multires_coupling_mesh_tags] +compulsory=false +description=List of mesh tag-names for the meshes used in the coupling miniapp +help=This is an ordered list of mesh names as loaded from the mesh + =input file for the coupling miniapp. It is expected that the mesh + =input file will contain the required intergrid maps between the meshes +length=: +sort-key=Panel-A01 +!string_length=default +type=character + +[namelist:multires_coupling=multires_coupling_mode] +compulsory=false +description=Describes the mode in which the coupling miniapp will be run +!enumeration=true +help=Test - a simple test case to test miniapp capabilities + =Jnr-Snr - dynamics and physics at a fine resolution coupled + =with dynamics, physics and chemistry at a coarse resolution + =Physics-Dynamics - physics and dynamics run at different resolutions + =and coupled together +sort-key=Panel-A04 +value-titles=Test, Jnr-Snr, Physics-Dynamics +values='test', 'jnr_snr', 'physics_dynamics' + +[namelist:multires_coupling=negative_correction] +compulsory=false +description=The type of correction to apply to intermesh mappings to prevent + =generation of negative values. +!enumeration=true +help=none - Map tracer variables without a mapping correction + =one_by_one - Each tracer is mapped with its own correction factor + =consistent - Variables of the same type, such as moisture variables or + = aerosols, are all given the same correction factor +sort-key=Panel-A05 +value-titles=none, one_by_one, consistent +values='none', 'one_by_one', 'consistent' + +[namelist:multires_coupling=orography_mesh_name] +compulsory=false +description=Name of the mesh used for reading in orography data +help=Orography is read in on this mesh +sort-key=Panel-A04 +!string_length=default +type=character + +[namelist:multires_coupling=physics_mesh_name] +compulsory=false +description=Tag-name for mesh used by physics +help=This is the mesh on which the physics parametrisations are run +sort-key=Panel-A03 +!string_length=default +type=character + +[namelist:multires_coupling=reconstruction] +compulsory=false +description=The strategy for the reconstruction used in the prolongation of + =scalar variables from coarse to fine meshes. +!enumeration=true +help=simple - simple reconstruction, performing a simple interpolation + = from neighbouring values. + =reversible - first performs the simple reconstruction, before adjusting + = it to make the prolongation process reversible with respect + = to the restriction operator. +sort-key=Panel-A06 +value-titles=simple, reversible +values='simple', 'reversible' + +[namelist:multires_coupling=recovery_order] +compulsory=false +description=The order of reconstruction to use when performing prolongation of + =scalar fields. +!enumeration=true +help=constant : injection, 0th order. + =linear : linear. +!kind=default +sort-key=Panel-A07 +value-titles=constant, linear +values='constant', 'linear' + +#============================================================================== +# ORBIT +#============================================================================== +[namelist:orbit] +compulsory=true +description=Orbital elements +ns=namelist/Model/Planet/Orbit +sort-key=Section-A05 +title=Orbit + +[namelist:orbit=arg_periapsis] +compulsory=true +description=Argument of periapsis [radians] +help=The angle between the ascending node and the periapsis (anticlockwise). + = + =The ascending node in this context is the point in the orbit where the + =planet passes through its autumn equinox for the northern hemisphere. + =The direction from the star to planet at this point in the orbit is the + =zero of the reference frame used here for the orbital elements. + =This direction is also where the host star appears in the sky as viewed + =from the planet at its northern hemisphere spring equinox. For the Earth + =this is known as the First Point of Aries. + =(Note, for a planet with zero obliquity, this zero direction is + =arbitrarily defined.) + = + =The periapsis is the point of closest approach in the planet's + =elliptical orbit. For a circular orbit it is undefined + =(can be set to zero.) + = + =As we are using the ascending node as the zero point for the reference + =frame here, then by definition, the longitude of the ascending node is + =zero, and the argument of periapsis is equal to the longitude of + =periapsis. For a planet around the sun this is known as the longitude + =of perihelion. +sort-key=Panel-A06 +type=real + +[namelist:orbit=arg_periapsis_inc] +compulsory=true +description=Increment to the argument of periapsis + =per Julian day from epoch [radians/day] +sort-key=Panel-A07 +type=real + +[namelist:orbit=eccentricity] +compulsory=true +description=Orbital Eccentricity [unitless] +help=The orbital eccentricity determines the amount by which the orbit + =deviates from a perfect circle. A value of 0 is a circular orbit, + =values between 0 and 1 form an elliptic orbit, 1 is a parabolic + =escape orbit, and greater than 1 is a hyperbola. +range=0.0:1.0 +sort-key=Panel-A04 +type=real + +[namelist:orbit=eccentricity_inc] +compulsory=true +description=Increment to eccentricity + =per Julian day from epoch [/day] +sort-key=Panel-A05 +type=real + +[namelist:orbit=elements] +compulsory=true +description=Orbital parameters +!enumeration=true +help=Parameters for the planet's orbit may be user-defined + =or given by the following presets: + =_________________________________________________________________ + =Earth: Fixed + = A standard Earth orbit that does not vary from one year to the next. + = The day number of the passage through perihelion is set to a mean + = value for the years 1995-2005. + = As the orbit is reset at the beginning of each year there will be a + = slight discontinuity in the orbital position. The epoch used is + = therefore always midday on the first day of the current year. + = The orbital elements used are taken from JPL and the Astronomical + = Almanac (1984) and equivalent to: + = eccentricity = 1.6710222E-02 + = eccentricity_inc = 0.0 + = arg_periapsis = 1.796767421 + = arg_periapsis_inc = 0.0 + = obliquity = 0.409092804 + = obliquity_inc = 0.0 + = semimajor_axis = 1.0 + = semimajor_axis_inc = 0.0 + = mean_anomaly = -0.037278428 + = mean_anomaly_inc = 0.01720278179 + = hour_angle = 0.0 + =_________________________________________________________________ + =Earth: Secular variation + = An Earth orbit with secular variations of the orbital elements + = described by A. L. Berger (1978), J. Atm. Sci., vol 35, p. 2362. + = These use higher order terms than the simple linear increments + = available with the user defined orbital elements. +sort-key=Panel-A01 +trigger=namelist:orbit=epoch: 'user' ; + =namelist:orbit=eccentricity: 'user' ; + =namelist:orbit=eccentricity_inc: 'user' ; + =namelist:orbit=arg_periapsis: 'user' ; + =namelist:orbit=arg_periapsis_inc: 'user' ; + =namelist:orbit=obliquity: 'user' ; + =namelist:orbit=obliquity_inc: 'user' ; + =namelist:orbit=semimajor_axis: 'user' ; + =namelist:orbit=semimajor_axis_inc: 'user' ; + =namelist:orbit=mean_anomaly: 'user' ; + =namelist:orbit=mean_anomaly_inc: 'user' ; + =namelist:orbit=hour_angle: 'user' ; +value-titles=User defined, Earth: Fixed, Earth: Secular variation +values='user', 'earth_fixed', 'earth_secular_variation' + +[namelist:orbit=epoch] +compulsory=true +description=Reference date in Julian Days [days] +help=The Julian day number on which the specified orbital elements + =apply. The increments are then the change in these orbital + =elements per Julian day from the given epoch. + = + =The J2000 epoch is specified by the Julian day number 2451545.0 + =which equates to midday on the 1st January 2000. +sort-key=Panel-A03 +type=real + +[namelist:orbit=fixed_azimuth_angle] +compulsory=true +description=Fixed stellar azimuth angle + =measured clockwise from north [radians] +help=This is an idealised setting where the solar / stellar azimuth angle + =will be the same for all points in the model. This overrides the + =angles calculated from the orbital elements but retains the distance + =of the planet from the host star. +sort-key=Panel-A17 +type=real + +[namelist:orbit=fixed_zenith_angle] +compulsory=true +description=Fixed stellar zenith angle for all points + =[radians] +help=This is an idealised setting where the solar / stellar zenith angle + =will be the same for all points in the model. This overrides the + =angles calculated from the orbital elements but retains the distance + =of the planet from the host star. +sort-key=Panel-A16 +type=real + +[namelist:orbit=hour_angle] +compulsory=true +description=Hour angle at epoch [radians] +help=The fraction of the planet's day since the host star was over + =the planet's prime meridian expressed as a fraction of a circle + =in radians. For the Earth, this is the angle the Sun has moved + =westwards since solar noon. + = + =This is the hour angle at the time of the given epoch. +sort-key=Panel-A14 +type=real + +[namelist:orbit=hour_angle_inc] +compulsory=true +description=Increment to hour angle + =per Julian day from epoch [radians/day] +help=This equates to 2*pi times the length of the planet's day over the + =length of a Julian day. +sort-key=Panel-A15 +type=real + +[namelist:orbit=mean_anomaly] +compulsory=true +description=Mean anomaly at epoch [radians] +help=The fraction of the orbital period since passage through periapsis + =expressed as a fraction of a circle in radians. If the orbit were + =completely circular then this would describe the actual angular + =position of the planet in the orbit (the true anomaly). + = + =This is the mean anomaly at the time of the given epoch. +sort-key=Panel-A12 +type=real + +[namelist:orbit=mean_anomaly_inc] +compulsory=true +description=Increment to mean anomaly + =per Julian day from epoch [radians/day] +help=This equates to 2*pi over the orbital period in Julian days. +sort-key=Panel-A13 +type=real + +[namelist:orbit=obliquity] +compulsory=true +description=Obliquity of the orbit [radians] +help=The angle between the rotational axis of the planet and the orbital axis, + =where the direction is defined so the rotation is in the same sense (i.e. + =anticlockwise). +sort-key=Panel-A08 +type=real + +[namelist:orbit=obliquity_inc] +compulsory=true +description=Increment to obliquity of the orbit + =per Julian day from epoch [radians/day] +sort-key=Panel-A09 +type=real + +[namelist:orbit=observer_lat] +compulsory=true +description=Orbital latitude of observer [radians] +help=Describes the angle from the plane of the planet's orbit to the + =position of a distant observer. Used for the calculation of diagnostics. +sort-key=Panel-A19 +type=real + +[namelist:orbit=observer_lon] +compulsory=true +description=Orbital longitude of observer [radians] +help=Describes the orbital angle (anticlockwise) from the ascending node + =of the planet's orbit to the position of a distant observer. Used + =for the calculation of diagnostics. +sort-key=Panel-A18 +type=real + +[namelist:orbit=semimajor_axis] +compulsory=true +description=Semi-major axis [AU] +help=One half of the major axis of the orbit, equivalent to the average + =between the orbital distance at periapsis and apoapsis (perihelion + =and aphelion for orbits around the Sun). For the Earth this was + =originally defined as 1 AU (astronomical unit), but 1 AU is now + =defined as exactly 149597870700 metres. +sort-key=Panel-A10 +type=real + +[namelist:orbit=semimajor_axis_inc] +compulsory=true +description=Increment to semi-major axis + =per Julian day from epoch [AU/day] +sort-key=Panel-A11 +type=real + +[namelist:orbit=spin] +compulsory=true +description=Treatment of stellar motion + =from planet's surface +!enumeration=true +help=The change in the hour angle of the sun as viewed from the + =planet's surface over the course of the day. + =This may be user defined or given by the following presets: + =_________________________________________________________________ + =Earth Day + = hour_angle_inc = exactly 2*pi + = The sun appears to make a full circuit in exactly one Earth day. + = This setting avoids any numerical drift due to an inexact user + = setting of 2*pi. + =_________________________________________________________________ + =Fixed Sun + = The position of the sun in the sky is fixed for all points. + = The solar zenith and azimuth angles are user supplied. +sort-key=Panel-A02 +trigger=namelist:orbit=hour_angle_inc: 'user' ; + =namelist:orbit=fixed_zenith_angle: 'fixed_sun' ; + =namelist:orbit=fixed_azimuth_angle: 'fixed_sun' ; +value-titles=User defined, Earth Day, Fixed Sun +values='user', 'earth_day', 'fixed_sun' + +#============================================================================== +# OROGRAPHY +#============================================================================== +[namelist:orography] +compulsory=true +description=Settings for the selected analytic orography profiles. +help=Settings for the Schar, Witch-of-Agnesi, Bell-shaped and DCMIP 2.0.0 analytic + =orography profiles in Cartesian and spherical coordinates + = (only spherical for DCMIP 2.0.0 profile, two bell-shaped mountains for spherical). +ns=namelist/Model/Planet/Orography +sort-key=Panel-A02 + +[namelist:orography=orog_init_option] +compulsory=true +description=Choice for initialization of orography fields +!enumeration=true +fail-if=this=='analytic' and namelist:orography=profile=="'none'" ; + =this=='ancil' and namelist:io=use_xios_io==".false." + =this=='start_dump' and namelist:io=use_xios_io==".false." +help=Choose how to initialize the orography fields: + = 'analytic' : Initialization is performed analytically. Profile must be + = set in the orography namelist option. + = 'ancil' : Initialize the orography from an ancillary file. Must be + = used with xios. + = 'start_dump' : Initialise the orography from the um2lfric start dump. +sort-key=Panel-A02 +trigger=namelist:files=orography_mean_ancil_path: 'ancil' ; + =namelist:orography=profile: 'analytic' ; + =namelist:extrusion=stretching_method: this != 'none'; +values='none', 'analytic', 'ancil','start_dump' + +[namelist:orography=profile] +compulsory=true +description=orography profile +!enumeration=true +fail-if=this == "'dcmip200'" and namelist:base_mesh=geometry != "'spherical'" ; + =this == "'none'" and namelist:orography=orog_init_option == "'analytic'" ; +help=none : No orography (flat surface) + =schar : Schar mountain profile + =agnesi : Witch-of-Agnesi mountain profile + =dcmip200 : DCMIP 2.0.0 mountain orography + =bell : Bell-shaped mountain profile +sort-key=Panel-A02 +trigger=namelist:orography_agnesi_cartesian: 'agnesi' ; + =namelist:orography_agnesi_spherical: 'agnesi' ; + =namelist:orography_bell_cartesian: 'bell' ; + =namelist:orography_bell_spherical: 'bell' ; + =namelist:orography_dcmip200_spherical: 'dcmip200' ; + =namelist:orography_schar_cartesian: 'schar' ; + =namelist:orography_schar_spherical: 'schar' ; +value-titles=None, Agnesi, Bell-shaped, Schar, DCMIP 2.0.0 +values='none', 'agnesi', 'bell', 'schar', 'dcmip200' + +#============================================================================== +# OROGRAPHY (AGNESI CARTESIAN) +#============================================================================== +[namelist:orography_agnesi_cartesian] +compulsory=true +description=Witch-of-Agnesi orography profile in Cartesian coordinates. +help=Settings for analytic orography profile of Witch-of-Agnesi mountain function + =in Cartesian biperiodic domain in x and/or y directions. + =Reference: Melvin et al. (2010), Section 4.3. +ns=namelist/Model/Planet/Agnesi cartesian +sort-key=Section-A03 +title=Agnesi cartesian profile + +[namelist:orography_agnesi_cartesian=direction] +compulsory=true +description=Direction of mountain (x, y, or xy) +!enumeration=true +help=See Melvin et al. (2010), Section 4.3. for the analytic form. +!kind=default +sort-key=Panel-A06 +value-titles=x, y, xy +values='x', 'y', 'xy' + +[namelist:orography_agnesi_cartesian=half_width_x] +compulsory=true +description=Half-width of mountain in x direction [m] +fail-if=this < 0.0 +help=See Melvin et al. (2010), Section 4.3. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[namelist:orography_agnesi_cartesian=half_width_y] +compulsory=true +description=Half-width of mountain in y direction [m] +fail-if=this < 0.0 +help=See Melvin et al. (2010), Section 4.3. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A03 +type=real + +[namelist:orography_agnesi_cartesian=mountain_height] +compulsory=true +description=Height of mountain [m] +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=See Melvin et al. (2010), Section 4.3. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:orography_agnesi_cartesian=x_centre] +compulsory=true +description=x coordinate of mountain centre [m] +help=See Melvin et al. (2010), Section 4.3. for the analytic form. +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:orography_agnesi_cartesian=y_centre] +compulsory=true +description=y coordinate of mountain centre [m] +help=See Melvin et al. (2010), Section 4.3. for the analytic form. +!kind=default +sort-key=Panel-A05 +type=real + +#============================================================================== +# OROGRAPHY (AGNESI SPHERICAL) +#============================================================================== +[namelist:orography_agnesi_spherical] +compulsory=true +description=Witch-of-Agnesi orography profile in spherical coordinates. +help=Settings for analytic orography profile of Witch-of-Agnesi mountain function + =in spherical domain. Reference: Wedi and Smolarkiewicz (2009), Section 4.1. +ns=namelist/Model/Planet/Agnesi spherical +sort-key=Section-A03 +title=Agnesi spherical profile + +[namelist:orography_agnesi_spherical=half_width] +compulsory=true +description=Half-width of mountain [m] +fail-if=this < 0.0 +help=See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[!namelist:orography_agnesi_spherical=lambda_centre] +compulsory=false +description=Latitude of mountain centre [radian] +expression=namelist:orography_agnesi_spherical=lambda_centre_dec * source:constants_mod=PI +help=See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +type=real + +[namelist:orography_agnesi_spherical=lambda_centre_dec] +compulsory=true +description=Latitude of mountain centre unscaled by PI +help=Scaled by PI in the configuration setup. + =See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +range=-0.5:0.5 +sort-key=Panel-A04 +type=real +warn-if=this > 0.5 ; + =this < -0.5 ; + +[!namelist:orography_agnesi_spherical=lambda_focus] +compulsory=false +description=Latitude of mountain focus [radian] +expression=namelist:orography_agnesi_spherical=lambda_focus_dec * source:constants_mod=PI +help=See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +type=real + +[namelist:orography_agnesi_spherical=lambda_focus_dec] +compulsory=true +description=Latitude of mountain focus unscaled by PI +help=Scaled by PI in the configuration setup. + =See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +range=-0.5:0.5 +sort-key=Panel-A06 +type=real +warn-if=this > 0.5 ; + =this < -0.5 ; + +[namelist:orography_agnesi_spherical=mountain_height] +compulsory=true +description=Height of mountain [m] +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[!namelist:orography_agnesi_spherical=phi_centre] +compulsory=false +description=Longitude of mountain centre [radian] +expression=namelist:orography_agnesi_spherical=phi_centre_dec * source:constants_mod=PI +help=See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +type=real + +[namelist:orography_agnesi_spherical=phi_centre_dec] +compulsory=true +description=Longitude of mountain centre unscaled by PI +help=Scaled by PI in the configuration setup. + =See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +range=0.0:2.0 +sort-key=Panel-A03 +type=real +warn-if=this > 2.0 ; + =this < 0.0 ; + +[!namelist:orography_agnesi_spherical=phi_focus] +compulsory=false +description=Longitude of mountain focus [radian] +expression=namelist:orography_agnesi_spherical=phi_focus_dec * source:constants_mod=PI +help=See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +type=real + +[namelist:orography_agnesi_spherical=phi_focus_dec] +compulsory=true +description=Longitude of mountain focus unscaled by PI +help=Scaled by PI in the configuration setup. + =See Wedi and Smolarkiewicz (2009), Section 4.1. for the analytic form. +!kind=default +range=0.0:2.0 +sort-key=Panel-A05 +type=real +warn-if=this > 2.0 ; + =this < 0.0 ; + +#============================================================================== +# OROGRAPHY (BELL CARTESIAN) +#============================================================================== +[namelist:orography_bell_cartesian] +compulsory=true +description=Bell-Shaped orography profile in Cartesian coordinates. +help=Settings for analytic orography profile of Bell-shaped mountain function + =in Cartesian biperiodic domain in x and/or y directions. + =Reference: Lock et al. (2012), Section 3.b. +ns=namelist/Model/Planet/Bell cartesian +sort-key=Section-A03 +title=Bell cartesian profile + +[namelist:orography_bell_cartesian=direction] +compulsory=true +description=Direction of mountain (x, y, or xy) +!enumeration=true +help=See Lock et al. (2012), Section 3.b. for the analytic form. +sort-key=Panel-A06 +value-titles=x, y, xy +values='x', 'y', 'xy' + +[namelist:orography_bell_cartesian=half_width_x] +compulsory=true +description=Half-width of mountain in x direction [m] +fail-if=this < 0.0 +help=See Lock et al. (2012), Section 3.b. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[namelist:orography_bell_cartesian=half_width_y] +compulsory=true +description=Half-width of mountain in y direction [m] +fail-if=this < 0.0 +help=See Lock et al. (2012), Section 3.b. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A03 +type=real + +[namelist:orography_bell_cartesian=mountain_height] +compulsory=true +description=Height of mountain [m] +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=See Lock et al. (2012), Section 3.b. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:orography_bell_cartesian=x_centre] +compulsory=true +description=x coordinate of mountain centre [m] +help=See Lock et al. (2012), Section 3.b. for the analytic form. +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:orography_bell_cartesian=y_centre] +compulsory=true +description=y coordinate of mountain centre [m] +help=See Lock et al. (2012), Section 3.b. for the analytic form. +!kind=default +sort-key=Panel-A05 +type=real + +#============================================================================== +# OROGRAPHY (Double Bell SPHERICAL) +#============================================================================== +[namelist:orography_bell_spherical] +compulsory=true +description=Double bell orography profile in spherical coordinates. +help=Settings for analytic orography profile of DCMIP 2.0.0 mountain function + =in spherical domain. + =Reference: Hughes & Jablonowski 2023 +ns=namelist/Model/Planet/Bell spherical +sort-key=Section-A03 +title=Bell spherical profile + +[namelist:orography_bell_spherical=lambda_centre1] +compulsory=true +description=Latitude of mountain centre in degrees +help=See Hughes & Jablonowski 2023 for the analytic form. +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:orography_bell_spherical=lambda_centre2] +compulsory=true +description=Latitude of mountain centre in degrees +help=See Hughes & Jablonowski 2023 for the analytic form. +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:orography_bell_spherical=mountain_height] +compulsory=true +description=Height of mountain [m] +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=See Hughes & Jablonowski 2023 for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:orography_bell_spherical=phi_centre1] +compulsory=true +description=Longitude of mountain centre in degrees +help=See Hughes & Jablonowski 2023 for the analytic form. +!kind=default +sort-key=Panel-A03 +type=real + +[namelist:orography_bell_spherical=phi_centre2] +compulsory=true +description=Longitude of mountain centre in degrees +help=See Hughes & Jablonowski 2023 for the analytic form. +!kind=default +sort-key=Panel-A03 +type=real + +[namelist:orography_bell_spherical=radius_lat] +compulsory=true +description=Mountain radius unscaled in degrees +help=See Hughes & Jablonowski 2023 for the analytic form. +!kind=default +sort-key=Panel-A02 +type=real + +[namelist:orography_bell_spherical=radius_lon] +compulsory=true +description=Mountain radius in degrees +help=See Hughes & Jablonowski 2023 for the analytic form. +!kind=default +sort-key=Panel-A02 +type=real + +#============================================================================== +# OROGRAPHY (DCMIP 2.0.0 SPHERICAL) +#============================================================================== +[namelist:orography_dcmip200_spherical] +compulsory=true +description=DCMIP 2.0.0 orography profile in spherical coordinates. +help=Settings for analytic orography profile of DCMIP 2.0.0 mountain function + =in spherical domain. + =Reference: Ullrich et al. (2012) DCMIP documentation, Section 2.0. +ns=namelist/Model/Planet/DCMIP2.0.0 spherical +sort-key=Section-A03 +title=DCMIP spherical profile + +[!namelist:orography_dcmip200_spherical=lambda_centre] +compulsory=false +description=Latitude of mountain centre [radian] +expression=namelist:orography_dcmip200_spherical=lambda_centre_dec * source:constants_mod=PI +help=See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +type=real + +[namelist:orography_dcmip200_spherical=lambda_centre_dec] +compulsory=true +description=Latitude of mountain centre unscaled by PI +help=Scaled by PI in the configuration setup. + =See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +range=0.0:2.0 +sort-key=Panel-A04 +type=real +warn-if=this > 2.0 ; + =this < 0.0 ; + +[namelist:orography_dcmip200_spherical=mountain_height] +compulsory=true +description=Height of mountain [m] +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[!namelist:orography_dcmip200_spherical=osc_half_width] +compulsory=false +description=Oscillation half-width of mountain function [radian] +expression=namelist:orography_dcmip200_spherical=osc_half_width_dec * source:constants_mod=PI +help=See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +type=real + +[namelist:orography_dcmip200_spherical=osc_half_width_dec] +compulsory=true +description=Oscillation half-width of mountain function unscaled by PI +fail-if=this < 0.0 +help=Scaled by PI in the configuration setup. + =See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A05 +type=real + +[!namelist:orography_dcmip200_spherical=phi_centre] +compulsory=false +description=Longitude of mountain centre [radian] +expression=namelist:orography_dcmip200_spherical=phi_centre_dec * source:constants_mod=PI +help=See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +type=real + +[namelist:orography_dcmip200_spherical=phi_centre_dec] +compulsory=true +description=Longitude of mountain centre unscaled by PI +help=Scaled by PI in the configuration setup. + =See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +range=0.0:2.0 +sort-key=Panel-A03 +type=real +warn-if=this > 2.0 ; + =this < 0.0 ; + +[!namelist:orography_dcmip200_spherical=radius] +compulsory=false +description=Mountain radius [radian] +expression=namelist:orography_dcmip200_spherical=radius_dec * source:constants_mod=PI +help=See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +type=real + +[namelist:orography_dcmip200_spherical=radius_dec] +compulsory=true +description=Mountain radius unscaled by PI +help=Scaled by PI in the configuration setup. + =See Ullrich et al. (2012) DCMIP documentation, Section 2.0. for the analytic form. +!kind=default +range=0.0:2.0 +sort-key=Panel-A02 +type=real +warn-if=this > 2.0 ; + =this < 0.0 ; + +#============================================================================== +# OROGRAPHY (SCHAR CARTESIAN) +#============================================================================== +[namelist:orography_schar_cartesian] +compulsory=true +description=Schar orography profile in Cartesian coordinates. +help=Settings for analytic orography profile of Schar mountain function + =in spherical domain. Reference: Melvin et al. (2010), Section 4.4. +ns=namelist/Model/Planet/Schar cartesian +sort-key=Section-A03 +title=Schar cartesian profile + +[namelist:orography_schar_cartesian=direction] +compulsory=true +description=Direction of mountain (x, y, or xy) +!enumeration=true +help=See Melvin et al. (2010), Section 4.4. for the analytic form. +sort-key=Panel-A06 +value-titles=x, y, xy +values='x', 'y', 'xy' + +[namelist:orography_schar_cartesian=half_width_x] +compulsory=true +description=Half-width of mountain in x direction [m] +fail-if=this < 0.0 +help=See Melvin et al. (2010), Section 4.4. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[namelist:orography_schar_cartesian=half_width_y] +compulsory=true +description=Half-width of mountain in y direction [m] +fail-if=this < 0.0 +help=See Melvin et al. (2010), Section 4.4. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A03 +type=real + +[namelist:orography_schar_cartesian=mountain_height] +compulsory=true +description=Height of mountain [m] +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=See Melvin et al. (2010), Section 4.4. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:orography_schar_cartesian=wavelength] +compulsory=true +description=Wavelength of Cos part of mountain function [m] +fail-if=this < 0.0 +help=See Melvin et al. (2010), Section 4.4. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A07 +type=real + +[namelist:orography_schar_cartesian=x_centre] +compulsory=true +description=x coordinate of mountain centre [m] +help=See Melvin et al. (2010), Section 4.4. for the analytic form. +!kind=default +sort-key=Panel-A04 +type=real + +[namelist:orography_schar_cartesian=y_centre] +compulsory=true +description=y coordinate of mountain centre [m] +help=See Melvin et al. (2010), Section 4.4. for the analytic form. +!kind=default +sort-key=Panel-A05 +type=real + +#============================================================================== +# OROGRAPHY (SCHAR SPHERICAL) +#============================================================================== +[namelist:orography_schar_spherical] +compulsory=true +description=Schar orography profile in spherical coordinates. +help=Settings for analytic orography profile of Schar mountain function + =in spherical domain. Reference: Wood et al. (2013), Section 7.1. +ns=namelist/Model/Planet/Schar spherical +sort-key=Section-A03 +title=Schar spherical profile + +[namelist:orography_schar_spherical=half_width] +compulsory=true +description=Half-width of mountain [m] +fail-if=this < 0.0 +help=See Wood et al. (2013), Section 7.1. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A02 +type=real + +[!namelist:orography_schar_spherical=lambda_centre] +compulsory=false +description=Latitude of mountain centre [radian] +expression=namelist:orography_schar_spherical=lambda_centre_dec * source:constants_mod=PI +help=See Wood et al. (2013), Section 7.1. for the analytic form. +!kind=default +type=real + +[namelist:orography_schar_spherical=lambda_centre_dec] +compulsory=true +description=Latitude of mountain centre unscaled by PI +help=Scaled by PI in the configuration setup. + =See Wood et al. (2013), Section 7.1. for the analytic form. +!kind=default +range=-0.5:0.5 +sort-key=Panel-A04 +type=real +warn-if=this > 0.5 ; + =this < -0.5 ; + +[namelist:orography_schar_spherical=mountain_height] +compulsory=true +description=Height of mountain [m] +fail-if=this < 0.0 ; + =this > namelist:extrusion=domain_height ; +help=See Wood et al. (2013), Section 7.1. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A01 +type=real + +[!namelist:orography_schar_spherical=phi_centre] +compulsory=false +description=Longitude of mountain centre [radian] +expression=namelist:orography_schar_spherical=phi_centre_dec * source:constants_mod=PI +help=See Wood et al. (2013), Section 7.1. for the analytic form. +!kind=default +type=real + +[namelist:orography_schar_spherical=phi_centre_dec] +compulsory=true +description=Longitude of mountain centre unscaled by PI +help=Scaled by PI in the configuration setup. + =See Wood et al. (2013), Section 7.1. for the analytic form. +!kind=default +range=0.0:2.0 +sort-key=Panel-A03 +type=real +warn-if=this > 2.0 ; + =this < 0.0 ; + +[namelist:orography_schar_spherical=wavelength] +compulsory=true +description=Wavelength of Cos part of mountain function [m] +fail-if=this < 0.0 +help=See Wood et al. (2013), Section 7.1. for the analytic form. +!kind=default +range=0.0: +sort-key=Panel-A07 +type=real + +#============================================================================== +# PHYSICS SECTION +#============================================================================== +[namelist:physics] +compulsory=true +description=Options for physics parametrizations +help=The placement variables indicate where a given physics routine is placed: + =if > 0: then placement is in fast physics + =if =0: then routine is not called + =if < 0: then placement is in slow physics +ns=namelist/Science + +[namelist:physics=bl_segment] +compulsory=true +description=Over-rides bl_segment_size in physics +fail-if=this < 0 ; +help=Boundary layer segment size. + = + =Setting bl_segment=0 will trigger the default behaviour + =of using the length of the local partition. +!kind=default +range=0: +type=integer + +[namelist:physics=blayer_placement] +compulsory=true +description=Boundary layer placement +!enumeration=true +help=Determines where the boundary layer scheme is called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A03 +value-titles=Fast physics, Slow physics +values='fast','slow' + +[namelist:physics=configure_segments] +compulsory=true +description=Configure OMP segment lengths in physics schemes +help=This will allow segmentation of physics loops and thereform OMP performance to be tuned +!kind=default +trigger=namelist:physics=bl_segment: .true. ; + =namelist:physics=conv_gr_segment: .true. ; + =namelist:physics=gw_segment: .true. ; + =namelist:physics=ls_ppn_segment: .true. ; + =namelist:physics=ussp_segment: .true. ; +type=logical + +[namelist:physics=conv_gr_segment] +compulsory=true +description=Number of segments to be processed in Gregory-Rowntree convection +help=This determines the segment size to be processed. + = This sub-segment will be processed in a loop. + = A sensible default seems to be 16. +!kind=default +range=1:9999999 +type=integer + +[namelist:physics=convection_placement] +compulsory=true +description=Convection placement +!enumeration=true +help=Determines where the convection scheme is called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A04 +value-titles=Fast physics, Slow physics +values='fast','slow' + +[namelist:physics=electric_placement] +compulsory=true +description=Electric placement +!enumeration=true +help=Determines where the electric (lightning scheme) is called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A16 +value-titles=Start of slow physics, After microphysics +values='slow','post_mphys' + +[namelist:physics=evap_condense_placement] +compulsory=true +description=Simple evaporation-condensation placement +!enumeration=true +help=Determines where the evaporation-condensation scheme is called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A03 +value-titles=Fast physics, Slow physics +values='fast','slow' + +[namelist:physics=gw_segment] +compulsory=true +description=Over-rides gw_seg_size in um physics +fail-if=this < 0 ; +help=Break segments gravity wave. + = + =Setting gw_segment=0 will trigger the default behaviour + =of using the length of the local partition. +!kind=default +range=0: +type=integer + +[namelist:physics=limit_drag_incs] +compulsory=true +description=Switch to ensure W2 drag increments are physically sensible +help=This will prevent the remapping of W3 -> W2 creating instances + = where the drag can accelerate the wind +!kind=default +ns=namelist/Science/Physics mapping +sort-key=Section-A03 +type=logical + +[namelist:physics=lowest_level] +compulsory=true +description=Option for updating lowest wtheta level prognostics +!enumeration=true +help=Physics codes typically only operate from the 1st wtheta level upwards. + = Hence we need to provide updates to the 0th wtheta level somehow. + = 3 options are available: + = + =Constant value: This forces the value of fields + = to be held constant below level 1. This is physically unrealistic + = and only provided for testing consistency with ENDGame. + = + =Constant gradient: Extrapolate the gradient between level 2 and level 1 + = to obtain the level 0 value, i.e. + = theta(z0) = theta(z1) - z1*(theta(z2)-theta(z1))/(z2-z1). + = + =Constant flux: Obtain the value at the surface using the surface + = fluxes from the bounary layer scheme, i.e. + = theta(z0) = theta(z1) + ftl/(cp*rhokh), + = where ftl is the surface heat flux and kh is the eddy diffusivity. +!kind=default +ns=namelist/Science/Physics mapping +sort-key=Section-A03 +value-titles=Constant value,Constant gradient,Constant flux +values='constant','gradient','flux' + +[namelist:physics=ls_ppn_segment] +compulsory=true +description=Large-scale precipitation OMP segment length +fail-if=this < 0 +help=Segment length used by large-scale precipitation scheme + =for OMP parallelization of loops. + = + =Setting ls_ppn_segment=0 will trigger the default behaviour + =of using the length of the local partition. +!kind=default +range=0: +type=integer + +[namelist:physics=microphysics_placement] +compulsory=true +description=Microphysics placement +!enumeration=true +help=Determines where the microphysics scheme is called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A05 +value-titles=Slow\ physics +values='slow' + +[namelist:physics=orographic_drag_placement] +compulsory=true +description=Orographic drag placement +!enumeration=true +help=Determines where the orographic drag scheme is called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A06 +value-titles=Slow\ physics +values='slow' + +[namelist:physics=radiation_placement] +compulsory=true +description=Radiative transfer placement +!enumeration=true +help=Determines where the radiation transfer scheme is called from. +ns=namelist/Science/Timestep placement +sort-key=Panel-A07 +value-titles=Slow\ physics +values='slow' + +[namelist:physics=sample_physics_scalars] +compulsory=true +description=Switch to sample rho, theta and exner at physics locations +help=If true then sample rho, theta and exner at physics locations, else use a + = Galerkin projection +!kind=default +ns=namelist/Science/Physics mapping +sort-key=Section-A01 +type=logical + +[namelist:physics=sample_physics_winds] +compulsory=true +description=Switch to sample FE winds at physics locations +help=If true then sample FE winds at physics locations, else use a + = Galerkin projection +!kind=default +ns=namelist/Science/Physics mapping +sort-key=Section-A02 +trigger=namelist:physics=sample_physics_winds_correction: .true. ; +type=logical + +[namelist:physics=sample_physics_winds_correction] +compulsory=false +description=When sampling physics winds, whether to include a correction at + =cubed sphere panel edges +help=If true then, when using a sampling method to convert physical wind + =components into a FE wind, include a correction to improve accuracy at the + =edges of cubed sphere panels +!kind=default +ns=namelist/Science/Physics mapping +sort-key=Section-A02b +type=logical + +[namelist:physics=smagorinsky_placement] +compulsory=true +description=Smagorinsky placement +!enumeration=true +help=Determines where the Smagorinsky mixing scheme is called from. + =Fast => from the fast physics predictors, equivalent to where the + = vertical mixing happens + =Outer => from the state variables in the dynamics outer-loop + = equivalent to the UM + =End => at the end of the timestep, after the solver +ns=namelist/Science/Timestep placement +sort-key=Panel-A09 +value-titles=Fast physics,Outer loop,Timestep end +values='fast','outer','end' + +[namelist:physics=spectral_gwd_placement] +compulsory=true +description=Spectral gravity wave drag placement +!enumeration=true +help=Determines where the spectral gravity wave drag scheme is called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A08 +value-titles=Slow\ physics +values='slow' + +[namelist:physics=stochastic_physics_placement] +compulsory=true +description=stochastic_physics placement +!enumeration=true +help=Determines where the stochastic physics schemes are called from. +!kind=default +ns=namelist/Science/Timestep placement +sort-key=Panel-A15 +value-titles=Fast\ physics +values='fast' + +[namelist:physics=ussp_segment] +compulsory=true +description=Gravity wave drag ussp OMP segment length +fail-if=this < 0 +help=Segment length used by ussp + =for OMP parallelization of loops. + = + =Setting ussp_seg_size=0 will trigger the default behaviour + =of using the length of the local partition. +!kind=default +range=0: +type=integer + +#============================================================================== +# PLANET +#============================================================================== +[namelist:planet=cp] +compulsory=true +description=[J/(kg K)] +fail-if=this <= 0.0 ; +help=Specific heat of dry air at constant pressure [J/(kg K)] +!kind=default +ns=namelist/Model/Planet/Properties +range=0.0: +sort-key=Panel-A05 +type=real + +[!namelist:planet=cv] +compulsory=false +expression=namelist:planet=cp - namelist:planet=rd +help=Specific heat of dry air at constant volume [J/(kg K)] +!kind=default +type=real + +[!namelist:planet=epsilon] +compulsory=false +description=Ratio of molecular weights: dry air / water +expression=namelist:planet=rd / source:driver_water_constants_mod=gas_constant_h2o +help=Molecular weight of water divided by molecular weight of dry air. + =[dimensionless] +!kind=default +type=real + +[namelist:planet=gravity] +compulsory=true +description=[m/(s^2)] +fail-if=this <= 0.0 ; +help=Surface equatorial value of gravity [m/s^2] +!kind=default +ns=namelist/Model/Planet/Properties +range=0.0: +sort-key=Panel-A01 +type=real + +[!namelist:planet=kappa] +compulsory=false +expression=namelist:planet=rd / namelist:planet=cp +help=Ratio of Rd and Cp [dimensionless] +!kind=default +type=real + +[namelist:planet=omega] +compulsory=true +description=[radians/second] +help=Planetary angular rotation rate. +!kind=default +ns=namelist/Model/Planet/Properties +sort-key=Panel-A03 +type=real + +[!namelist:planet=one_over_kappa] +compulsory=false +expression=namelist:planet=cp / namelist:planet=rd +help=Inverse ratio of Rd and Cp [dimensionless] +!kind=default +type=real + +[namelist:planet=p_zero] +compulsory=true +description=[Pa] +help=Reference surface pressure [Pa] +!kind=default +ns=namelist/Model/Planet/Properties +sort-key=Panel-A06 +type=real + +[namelist:planet=rd] +compulsory=true +description=[J/(kg K)] +help=Gas constant for dry air [J/(kg K)] +!kind=default +ns=namelist/Model/Planet/Properties +sort-key=Panel-A04 +type=real + +[!namelist:planet=recip_epsilon] +compulsory=false +expression=source:driver_water_constants_mod=gas_constant_h2o / namelist:planet=rd +help=Reciprocal of ratio molecular mass of water to dry air. + =[dimensionless] +!kind=default +type=real + +[!namelist:planet=scaled_omega] +compulsory=false +expression=namelist:planet=omega * namelist:planet=scaling_factor +help=?????? + =?????? +!kind=default +type=real + +#============================================================================== +# Section choice namelist +#============================================================================== +[namelist:section_choice] +compulsory=true +description=Specify section choices for this configuration. +ns=namelist/Science/Section choice +sort-key=A + +[namelist:section_choice=aerosol] +compulsory=true +description=Which aerosol scheme to use +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; +help=The following aerosol options are available from the aerosol namelist + = GLOMAP-mode climatology + = + =Note that only one of these aerosol options can be used at a time. +sort-key=Panel-A01 +trigger=namelist:aerosol: this == "'um'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=boundary_layer] +compulsory=true +description=Which boundary layer turbulence parametrization to use +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; +help=Either the boundary layer can be switched off and no surface drag applied, + =or the UM scheme based on Lock et al (2000 MWR) can be used. +sort-key=Panel-A02 +trigger=namelist:physics=blayer_placement: this != "'none'" ; + =namelist:physics=lowest_level: this == "'um'" ; + =namelist:section_choice=convection: this != "'none'" ; + =namelist:blayer: this == "'um'" ; + =namelist:mixing=method: this == "'um'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=chemistry] +compulsory=true +description=Which Chemistry model to use +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; +help=The following Chemistry schemes are available from the chemistry namelist + = UM: Offline oxidants + = UM: Strattrop + =Note that only one of these chemistry options can be used at a time. +sort-key=Panel-A01 +trigger=namelist:chemistry: this == "'um'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=cloud] +compulsory=true +description= + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; + =this != "'none'" and namelist:formulation=moisture_formulation == "'dry'" ; +help=?????? + =?????? +sort-key=Panel-A03 +trigger=namelist:cloud: this == "'um'" ; + =namelist:physics=evap_condense_placement: this == "'evap_condense'" ; + =namelist:section_choice=microphysics: this != "'none'" ; +value-titles=None, Unified Model, Evaporation-Condensation +values='none', 'um', 'evap_condense' + +[namelist:section_choice=convection] +compulsory=true +description= + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; + =this != "'none'" and namelist:section_choice=boundary_layer == "'none'" ; +help=?????? + =?????? +sort-key=Panel-A04 +trigger=namelist:physics=convection_placement: this != "'none'" ; + =namelist:convection=cv_scheme: this == "'um'" ; + =namelist:cloud=mphys_erosion: this == "'none'"; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=dynamics] +compulsory=true +description= + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_wavedynamics == ".false." ; +help=?????? + =?????? +sort-key=Panel-A05 +value-titles=None, GungHo +values='none', 'gungho' + +[namelist:section_choice=electric] +compulsory=true +description=Use electrification (lightning) scheme +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; + =this != "'none'" and namelist:section_choice=microphysics == "'none'" ; +help=Selecting an electification scheme allows the model to produce + =lightning from appropriate thunderstorm clouds. This scheme requires + =a working cloud microphysics scheme as a prerequisite. +sort-key=Panel-A12 +trigger=namelist:physics=electric_placement: this != "'none'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=external_forcing] +compulsory=true +description=Use external forcing of thermodynamic variables +sort-key=Panel-A12 +trigger=namelist:external_forcing: .true.; +type=logical + +[namelist:section_choice=iau] +compulsory=true +description=Use IAU +help=Logical namelist variable to say whether the IAU is used +sort-key=Panel-A12 +trigger=namelist:files=iau_path: .true.; + =namelist:iau=iau_ainc_multifile: .true.; + =namelist:iau=iau_mode: .true.; + =namelist:iau=iau_pc2: .true.; + =namelist:iau=iau_tendency_ainc: .true.; + =namelist:iau=iau_use_level_one_temp: .true.; + =namelist:iau=iau_wet_density: .true.; + =namelist:iau=iau_use_addinf: .true.; + =namelist:iau=iau_use_bcorr: .true.; +type=logical + +[namelist:section_choice=iau_sst] +compulsory=true +description=Use iau_sst +help=Logical namelist variable to say whether the IAU is used for sst increments +sort-key=Panel-A12 +trigger=namelist:files=iau_sst_path: .true.; +type=logical + +[namelist:section_choice=iau_surf] +compulsory=true +description=Use iau_surf +help=Logical namelist variable to say whether the IAU is used for surface increments +sort-key=Panel-A12 +trigger=namelist:files=iau_surf_path: .true.; +type=logical + +[namelist:section_choice=methane_oxidation] +compulsory=true +description=Use methane oxidation +help=Selecting methane_oxidation allows the calculation of + =chemical water vapour change due to methane oxidation and photolysis, + =following the method used at ECMWF (Untch et al (ECMWF Newsletter No + =87 winter 1998/99 pp 2-8) and Simmons (pers. comm.)). The model + =methane mixing ratio is implicit and derived from the assumption that + =2 [CH4] + [H2O] = 3.75 ppmm throughout the stratosphere. + = + =The methane oxidation and hydrogen photolysis rate coefficients vary + =only with pressure, which is calculated for a standard atmosphere + =assuming a surface pressure of namelist:planet=p_zero. +sort-key=Panel-A11 +type=logical + +[namelist:section_choice=microphysics] +compulsory=true +description= + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; + =this != "'none'" and namelist:section_choice=cloud == "'none'" ; +help=?????? + =?????? +sort-key=Panel-A06 +trigger=namelist:physics=microphysics_placement: this != "'none'" ; + =namelist:section_choice=electric: this!= "'none'"; + =namelist:microphysics: this == "'um'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=orographic_drag] +compulsory=true +description=Orographic drag scheme + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; +help=Orographic drag scheme + ====================================== + =Accounts for drag forces on the atmosphere due to interaction + =with sub-grid mountains. + = + =Options are: + =_________________________________________________________________ + =None: + = No orographic drag scheme applied. + =_________________________________________________________________ + =UM: + = The orographic drag scheme from the Unified Model. + = + = This scheme is based on the Lott and Miller (1997) parametrization and + = includes drag contributions from low-level flow blocking and + = orographic gravity waves. It accounts for sub-grid orography of + = horizontal scales larger than 6 km (i.e. hydrostatic scales). + = (see UM Documentation paper, UMDP022). +sort-key=Panel-A07 +trigger=namelist:physics=orographic_drag_placement: this != "'none'" ; + =namelist:orographic_drag: this == "'um'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=radiation] +compulsory=true +description= + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; +help=?????? + =?????? +sort-key=Panel-A08 +trigger=namelist:radiation: this == "'socrates'" ; + =namelist:physics=radiation_placement: this != "'none'" ; + =namelist:orbit: this != "'none'" ; + =namelist:star: this != "'none'" ; +value-titles=None, SOCRATES +values='none', 'socrates' + +[namelist:section_choice=spectral_gwd] +compulsory=true +description= + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; +help=Spectral gravity wave drag scheme + ====================================== + =Accounts for drag forces on the atmosphere due to non-orographic + =gravity wave sources. + = + =Options are: + =_________________________________________________________________ + =None: + = No spectral gravity wave drag scheme applied. + =_________________________________________________________________ + =UM: + = The Ultra Simple Spectral Parametrization (USSP) of gravity wave drag + = from the Unified Model. + = + = The approach taken is that of Warner and McIntyre (1996), Warner and + = McIntyre (1999) and Warner and McIntyre (2001) with further + = modifications (Scaife et al., 2002; Scaife et al., 2000). + = + = The scheme includes an option for convective gravity wave sources. + = + = See UM documentation page 034 (UMDP034). +sort-key=Panel-A09 +trigger=namelist:physics=spectral_gwd_placement: this != "'none'" ; + =namelist:spectral_gwd: this == "'um'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=stochastic_physics] +compulsory=true +description=Sets of Stochastic Physics to use + = +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; + =this != "'none'" and namelist:section_choice=stochastic_physics == "'none'" ; +help=UM: + = The Stochastic Perturbation of Tendencies (SPT) +sort-key=Panel-A15 +trigger=namelist:physics=stochastic_physics_placement: this != "'none'" ; + =namelist:stochastic_physics: this == "'um'" ; +value-titles=None, Unified Model +values='none', 'um' + +[namelist:section_choice=surface] +compulsory=true +description=Which surface scheme to use +!enumeration=true +fail-if=this != "'none'" and namelist:formulation=use_physics == ".false." ; +help=Currently JULES is the only surface scheme available for use +sort-key=Panel-A10 +trigger=namelist:surface: this == "'jules'" ; + =namelist:jules_hydrology: this == "'jules'" ; + =namelist:jules_model_environment_lfric: this == "'jules'" ; + =namelist:jules_nvegparm: this == "'jules'" ; + =namelist:jules_pftparm: this == "'jules'" ; + =namelist:jules_radiation: this == "'jules'" ; + =namelist:jules_sea_seaice: this == "'jules'" ; + =namelist:jules_soil: this == "'jules'" ; + =namelist:jules_snow: this == "'jules'" ; + =namelist:jules_surface: this == "'jules'" ; + =namelist:jules_surface_types: this == "'jules'" ; + =namelist:jules_urban: this == "'jules'" ; + =namelist:jules_vegetation: this == "'jules'" ; +value-titles=None, JULES +values='none','jules' + +#============================================================================== +# MASS MATRIX SOLVER +#============================================================================== +[namelist:solver] +compulsory=true +description=?????? +help=This namelist is for using iteratives solvers for the inversion of mass matrices +ns=namelist/Science/Dynamics/Mass Matrix Solver +sort-key=Section-A04 + +[namelist:solver=fail_on_non_converged] +compulsory=true +description=Cause the solver to return an error if the maximum number of iterations are reached and + =residual has not been reduced below the desired tolerance otherwise the solver will exit even + =if it has not converged. If monitor_convergence is set to false then this setting has no effect +help=Return an error if solver fails to converge +sort-key=Panel-A07 +type=logical + +[namelist:solver=gcrk] +compulsory=true +description=?????? +help=Dimension of the approximate Krylov subspace. + =In other words, it is the number of potential + =residual vectors to calculate at each + =iteration of the solver. +!kind=default +sort-key=Panel-A05 +type=integer + +[namelist:solver=jacobi_relaxation] +compulsory=true +description=?????? +help=Relaxtion factor to use in the Jacobi solver +!kind=default +sort-key=Panel-A11 +type=real + +[namelist:solver=maximum_iterations] +compulsory=true +description=?????? +fail-if=this < 1 ; +help=Iteration limit for solver +!kind=default +range=1: +sort-key=Panel-A02 +type=integer + +[namelist:solver=method] +compulsory=true +description=?????? +!enumeration=true +help=?????? + =?????? +sort-key=Panel-A01 +trigger=namelist:solver=jacobi_relaxation: this == "'jacobi'"; +value-titles=biconjugate gradient stabilized, + =conjugate gradient, + =generalized conjugate residual, + =generalized minimal residual, + =flexible generalized minimal residual, + =precondition only, + =jacobi, + =chebyshev +values='bicgstab', 'cg', 'gcr', 'gmres', 'fgmres', 'prec_only', 'jacobi', 'chebyshev' + +[namelist:solver=monitor_convergence] +compulsory=true +description=Computes and prints out convergence information for the iterative solver and if the + =error has been reduced below the tolerance then the solver will exit. If set to false + =the solver will always perform the maximum number of iterations before exiting +help=Monitor convergence of the iterative mass matrix solver +sort-key=Panel-A06 +trigger=namelist:solver=fail_on_non_converged: .true.; +type=logical + +[namelist:solver=preconditioner] +compulsory=true +description=?????? +!enumeration=true +help=?????? + =?????? +sort-key=Panel-A04 +value-titles=None, Diagonal +values='none', 'diagonal' + +[namelist:solver=tolerance] +compulsory=true +description=?????? +help=Relative tolerance of solver +!kind=default +sort-key=Panel-A03 +type=real + +#============================================================================== +# STAR +#============================================================================== +[namelist:star] +compulsory=true +description=Properties of host star +ns=namelist/Model/Planet/Star +sort-key=Section-A04 +title=Star + +[namelist:star=stellar_constant] +compulsory=true +description=Stellar irradiance at 1 AU [Wm-2] +help=The flux received from the host star at a distance of 1 astronomical unit. + =For the Sun, this is the "Solar constant". +sort-key=Panel-A01 +type=real + +[namelist:star=stellar_radius] +compulsory=true +description=Radius of host star [m] +help=Radius at the photosphere of the host star used for the calculation + =of diagnostics. +sort-key=Panel-A02 +type=real + +#============================================================================== +# IDEALISED FORCING - PROFILE OF TEMPERATURE TENDENCY +#============================================================================== +[namelist:temp_tend_data] +compulsory=true +description=Settings for temperature forcing +ns=namelist/Science/External Forcing/Temperature Forcing +sort-key=A1 +title=Temperature forcing + +[namelist:temp_tend_data=coordinate] +compulsory=true +description=Vertical coordinate for temperature tendency forcing +!enumeration=true +help=Temperature tendency forcing profiles may be specified with either height + =or pressure as the vertical coordinate. In both cases the coordinate + =information is entered using the heights array. + =Height: height in metres above sea-level. Values should be monotonically increasing. + =Pressure: pressure level in Pascals. Values should be monotonically decreasing. +!kind=default +ns=namelist/Science/External Forcing/Temperature Forcing +sort-key=Panel-A01b +value-titles=Height, Pressure +values='height', 'pressure' + +[namelist:temp_tend_data=heights] +!bounds=namelist:temp_tend_data=number_heights +compulsory=true +description=Temperature tendency heights +fail-if=len(this) != namelist:temp_tend_data=number_heights +help=Heights for temperature tendency profile. If in ascending order, these are + =taken to be height in metres. Heights specified in descending order are + =taken to be pressure coordinate in Pascals. +!kind=default +length=: +ns=namelist/Science/External Forcing/Temperature Forcing +sort-key=Panel-A01c +type=real + +[namelist:temp_tend_data=number_heights] +compulsory=true +description=Size of temperature tendency profile +help=Number of data points in the temperature tendency profile. +!kind=default +ns=namelist/Science/External Forcing/Temperature Forcing +range=0:100 +sort-key=Panel-A01a +type=integer + +[namelist:temp_tend_data=number_times] +compulsory=true +description=Number of temperature tendency profile +help=Temperature tendency profiles at the times specified in + =the times array. +!kind=default +ns=namelist/Science/External Forcing/Temperature Forcing +range=0:100 +sort-key=Panel-A01a +type=integer + +[namelist:temp_tend_data=profile_data] +!bounds=namelist:temp_tend_data=number_heights * namelist:temp_tend_data=number_times +compulsory=true +description=Temperature tendency data +fail-if=len(this) != namelist:temp_tend_data=number_heights * namelist:temp_tend_data=number_times +help=Temperature tendency (K/s) +!kind=default +length=: +ns=namelist/Science/External Forcing/Temperature Forcing +sort-key=Panel-A01d +type=real + +[namelist:temp_tend_data=times] +!bounds=namelist:temp_tend_data=number_times +compulsory=true +description=Temperature tendency times +fail-if=len(this) != namelist:temp_tend_data=number_times +help= +!kind=default +length=: +ns=namelist/Science/External Forcing/Temperature Forcing +sort-key=Panel-A01c +type=real + +#============================================================================== +# RELAXATION OF POTENTIAL TEMPERATURE +#============================================================================== +[namelist:theta_relax] +compulsory=false +description=Settings for relaxation of potential temperature +ns=namelist/Science/External Forcing/Theta Relaxation +sort-key=A2 +title=Potential temperature relaxation + +[namelist:theta_relax=coordinate] +compulsory=true +description=Vertical coordinate for potential temperature relaxation +!enumeration=true +help=Target vertical profiles, towards which potential temperature is relaxed, may be + =specified with either height or pressure as the vertical coordinate. + =In both cases the coordinate information is entered using the + =theta_relax_heights array. + =Height: height in metres above sea-level. Values should be monotonically increasing. + =Pressure: pressure level in Pascals. Values should be monotonically decreasing. + =Note that while the pressure coordinate is specified in Pascals, this is + =converted to Exner for the purposes of interpolating the target profile. +!kind=default +ns=namelist/Science/External Forcing/Theta Relaxation +sort-key=Panel-A03a +value-titles=Height, Pressure +values='height', 'pressure' + +[namelist:theta_relax=heights] +!bounds=namelist:theta_relax=number_heights +compulsory=true +description=Coordinate information for relaxation target profile +help=The vertical coordinate information for the target profile + =may be either heights, in metres, or pressure, in Pascals. + =Use theta_relax_coord to determine which coordinate variable + =is used. + =The order in which coordinate values are listed should correspond + =with the order in which the profile data are listed. + =Note also that relaxation is applied only within the region + =defined by the limits of the coordinate data provided. The + =target profile is not extrapolated beyond this range. +!kind=default +length=: +ns=namelist/Science/External Forcing/Theta Relaxation +sort-key=Panel-A03b +type=real + +[namelist:theta_relax=number_heights] +compulsory=true +description=Size of theta_relax_heights array +help=Number of points in the target profile for potential temperature. +!kind=default +ns=namelist/Science/External Forcing/Theta Relaxation +range=0:200 +sort-key=Panel-A03a +type=integer + +[namelist:theta_relax=number_times] +compulsory=true +description=Number of target profiles towards which potential temperature is relaxed +help=At each timestep an increment is applied to potential temperature to relax its + =horizontal mean towards a specified profile. This profile may be time-varying, + =in which case profiles are specified at multiple times and linear interpolation + =is used to evaluate the profile at the current model time. +!kind=default +ns=namelist/Science/External Forcing/Theta Relaxation +range=0: +sort-key=Panel-A03c +type=integer + +[namelist:theta_relax=profile_data] +!bounds=namelist:theta_relax=number_heights * namelist:theta_relax=number_times +compulsory=true +description=Target profile data for relaxation of potential temperature (Kelvin) +help=Values of dry potential temperature (in Kelvin) in the target vertical profiles + =for dry potential temperature. Profiles are listed sequentially in time. +!kind=default +length=: +ns=namelist/Science/External Forcing/Theta Relaxation +sort-key=Panel-A03d +type=real + +[namelist:theta_relax=times] +!bounds=namelist:theta_relax=number_times +compulsory=true +description=Timestamps (in seconds) of target profiles +help=Validity times (in seconds) of the target profiles for Newtonian + =relaxation of dry potential temperature. +!kind=default +length=: +ns=namelist/Science/External Forcing/Theta Relaxation +sort-key=Panel-A03c +type=real + +[namelist:theta_relax=timescale] +compulsory=true +description=Relaxation timescale in seconds +help=Time-scale in seconds on which dry potential temperature is relaxed to its + =target profile. This is the e-fold time, which is related to the + =half-life time by half_life = ln(2) * timescale. +!kind=default +ns=namelist/Science/External Forcing/Theta Relaxation +sort-key=Panel-A03e +type=real + +#============================================================================== +# TIMESTEPPING +#============================================================================== +[namelist:timestepping=alpha] +compulsory=true +description=?????? +help=Time off-centering parameter +!kind=default +sort-key=Panel-A03 +type=real + +[!namelist:timestepping=beta] +compulsory=false +expression=1.0_r_def - namelist:timestepping=alpha +help=?????? + =?????? +!kind=default +type=real + +[namelist:timestepping=inner_iterations] +compulsory=true +description=?????? +fail-if=this < 1 ; +help=Number of inner (Newton) iterations to do +!kind=default +range=1: +sort-key=Panel-A08 +type=integer + +[namelist:timestepping=method] +compulsory=true +description=Use either explicit Runge-Kutta timestepping or (iterative-) Semi-Implicit scheme +!enumeration=true +help=Set the timestepping method for the GungHo dynamical core, either a fully explicit multi-stage + =Runge-Kutta method ('rk') or an (iterative-) Semi-Implicit scheme ('semi_implicit'). + =It is also possible to set 'no_timestepping'. There are no calls to dynamics or physics and the prognostic fields remain the same. However, time-varying fields such as ancillaries, and LBCs are still updated on each timestep, and diagnostics are output. + ='no_timestepping' is intended as a temporary switch required for basic-ral development. + =But it may also be useful for testing the tangent linear in 4DVar. +sort-key=Panel-A01 +trigger=namelist:timestepping=tau_t: 'semi_implicit' ; + =namelist:timestepping=tau_r: 'semi_implicit' ; + =semi-implicit: 'semi_implicit' ; + =namelist:timestepping=outer_iterations: 'semi_implicit', 'jules' ; + =namelist:timestepping=inner_iterations: 'semi_implicit' ; +value-titles=Semi-implicit, Runge-Kutta, No-timestepping, JULES +values='semi_implicit', 'rk', 'no_timestepping', 'jules' + +[namelist:timestepping=outer_iterations] +compulsory=true +description=?????? +fail-if=this < 1 ; +help=Number of outer (advection) iterations to do +!kind=default +range=1: +sort-key=Panel-A07 +type=integer + +[namelist:timestepping=runge_kutta_method] +compulsory=true +description=????? +!enumeration=true +fail-if= +help=????? + =????? +ns=namelist/Job/Timestepping/runge kutta +sort-key=Panel-A01 +value-titles=Foward Euler, + =Stong Stability Preserving: Order-2, + =Stong Stability Preserving: Order-3, + =Stong Stability Preserving: Order-4, + =Stong Stability Preserving: Order-5 +values='forward_euler', 'ssp2', 'ssp3', 'ssp4', 'ssp5' + +[namelist:timestepping=spinup_alpha] +compulsory=true +description=?????? +help=If true then spin up alpha over the spin up period +!kind=default +sort-key=Panel-A11 +trigger=namelist:timestepping=spinup_period: .true.; +type=logical + +[namelist:timestepping=tau_r] +compulsory=true +description=?????? +fail-if=this < 0.0 +help=Relaxation parameter for density in semi-implicit method +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +sort-key=Panel-A06 +type=real + +[namelist:timestepping=tau_t] +compulsory=true +description=?????? +fail-if=this < 0.0 +help=Relaxation parameter for potential temperature in semi-implicit method +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +sort-key=Panel-A05 +type=real + +[namelist:timestepping=tau_u] +compulsory=true +description=?????? +fail-if=this < 0.0 +help=Relaxation parameter for velocity in semi-implicit method +!kind=default +ns=namelist/Job/Timestepping/semi-implicit +range=0.0: +sort-key=Panel-A04 +type=real + +#============================================================================== +# TRANSPORT +#============================================================================== +[namelist:transport] +compulsory=true +description=?????? +help=?????? + =?????? +ns=namelist/Science/Dynamics/Transport +sort-key=Section-A10 + +[namelist:transport=adjust_theta] +compulsory=true +description=Whether to apply dry static adjustment to theta after transport. +fail-if= +help=Applies an insertion sort to theta within a column after it is transported + =to ensure that the resulting theta profile is stable. +!kind=default +sort-key=Panel-A25 +trigger=namelist:transport=adjust_theta_above: .true.; +type=logical + +[namelist:transport=adjust_theta_above] +compulsory=true +description=Height, in metres above sea level, above which to apply dry static + =adjustment to theta. +fail-if= +help=The dry static adjustment will be applied to theta above this height. +!kind=default +sort-key=Panel-A25 +trigger= +type=real + +[namelist:transport=adjust_tracer_equation] +compulsory=true +description=Adjusts the equation form of conservative tracer groups to + =advective form if Watkins algorithm is unable to fix large + =Lipschitz numbers for consistent transport. This will break + =tracer convservation for any time steps this is needed. +fail-if= +help=Must be used with FFSL and SWIFT splittings +!kind=default +sort-key=Panel-A31 +trigger= +type=logical + +[namelist:transport=adjust_vhv_wind] +compulsory=true +description=Adjusts the first and final vertical winds in a Strang VHV splitting + =to avoid breaking any Lipschitz condition. +fail-if= +help=Must be used with 3D FFSL and SWIFT splittings +!kind=default +sort-key=Panel-A31 +trigger= +type=logical + +[namelist:transport=ageofair_reset_level] +compulsory=false +description=Level below which ageofair is reset to zero +fail-if=this < 0 ; +range=0: +sort-key=Panel-A01 +type=integer + +[namelist:transport=broken_w2_projection] +compulsory=true +description=Switch to control whether to reconstruct the wind from its + =components in W3 via the broken W2 space, to avoid this leading to + =overshoots and undershoots. +fail-if= +help=Set as true to reconstruct the transported wind increments via broken W2, + =else perform a Galerkin projection into W2. +!kind=default +sort-key=Panel-A21 +trigger= +type=logical + +[namelist:transport=calculate_detj] +compulsory=true +description=Method to compute Det(J) at W2 DoFs used in vertical departure point calculations. +!enumeration=true +help=Det(J) at W2 DoFs is used to compute the vertical departure points for the + =FFSL and semi-Lagrangian transport schemes. To compute Det(J) at vertical W2 + =points we choose either an average of Det(J) from neighbouring cells, or + =use Det(J) from the upwind cell. +sort-key=Panel-A30 +value-titles=Averaged Det(J), Upwind Det(J) +values='averaged', 'upwind' + +[namelist:transport=cap_density_predictor] +compulsory=true +description=Value which limits the divergence factor in the density predictor. +fail-if=this < 0.0 ; +help=The density predictor has the form density*divergence_factor. This option + =provides a value that limits the divergence_factor to be in the range + =1-value <= divergence_factor <= 1+value. +range=0.0:1.0 +sort-key=Panel-A05 +type=real + +[namelist:transport=cfl_mol_1d_stab] +compulsory=false +description=Max stability Courant number for 1D-MOL (One-Dimensional Method of Line). +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:transport=cfl_mol_2d_stab] +compulsory=false +description=Max stability Courant number for 2D-MOL (2-Dimensional Method of Line). +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:transport=cfl_mol_3d_stab] +compulsory=false +description=Max stability Courant number for 3D-MOL (3-Dimensional Method of Line). +fail-if=this < 0.0 ; +range=0.0: +sort-key=Panel-A01 +type=real + +[namelist:transport=cheap_update] +compulsory=true +description=Switch to control whether to use the cheap transport update with + =the semi-implicit time stepping. +fail-if=this == ".true." and namelist:transport=substep_transport != "'off'" +help=Set as true to use the cheap update in gungho transport. The cheap update uses + =wind_n as the advecting wind during the first outer iteration, and + =(wind_np1 - wind_n)/2 for the second outer iteration. The advection increments + =are then summed to give transport with (wind_np1 + wind_n)/2 as the advecting + =wind. The aim is that the second iteration transport has a much smaller CFL and + =so is cheaper than the full transport. For more outer iterations we use + =(wind_np1_current_iteration - wind_np1_previous_iteration)/2 as the advecting + =wind. +!kind=default +sort-key=Panel-A21 +trigger= +type=logical + +[namelist:transport=consistent_metric] +compulsory=true +description=?????? +fail-if= +help=Compute metric terms with the advection scheme +!kind=default +sort-key=Panel-A05 +trigger= +type=logical + +[namelist:transport=dep_pt_stencil_extent] +compulsory=true +description=Determines the size of the stencil extent used to find departure + =points, and hence the size of halos of the model. +fail-if=this < 1 ; +help=This should be set to the expected maximum Courant number for horizontal + =flow. This value is then equal to the maximum departure distance in + =number of cells. +!kind=default +range=1: +sort-key=Panel-A01 +type=integer + +[namelist:transport=dry_field_name] +compulsory=false +description=Name of the dry field used for conservative tracer transport +fail-if= +help=This must be the name of one of the other transported fields +sort-key=Panel-A06 +!string_length=default +type=character + +[namelist:transport=enforce_min_value] +!bounds=namelist:transport=profile_size +compulsory=true +description=Enforce a minimum value for the transported field +help= +!kind=default +length=: +sort-key=Panel-A04c +type=logical + +[namelist:transport=equation_form] +!bounds=namelist:transport=profile_size +compulsory=true +description=Which form of the transport equation to use for each variable. +fail-if=len(this) != namelist:transport=profile_size ; +help=The options are: 1 = 'conservative', 2 = 'advective', 3 = 'consistent' +!kind=default +length=: +sort-key=Panel-A04a +type=integer + +[namelist:transport=ffsl_inner_order] +compulsory=true +description=Order of FFSL scheme for inner operators. +fail-if= +help=The order of the inner operators for the FFSL scheme. This also specifies + =the size of the stencil needed for the reconstruction. Note that Nirvana + =uses a quadratic reconstruction but a smaller stencil than PPM due to the + =calculation of the cell edge values. Either + =0: Piecewise Constant Method (PCM) + =1: Nirvana Method + =2: Piecewise Parabolic Method (PPM) +!kind=default +!range= +sort-key=Panel-A31 +trigger= +type=integer + +[namelist:transport=ffsl_outer_order] +compulsory=true +description=Order of FFSL scheme for outer operators. +fail-if= +help=The order of the outer operators for the FFSL scheme. This also specifies + =the size of the stencil needed for the reconstruction. Note that Nirvana + =uses a quadratic reconstruction but a smaller stencil than PPM due to the + =calculation of the cell edge values. Either + =0: Piecewise Constant Method (PCM) + =1: Nirvana Method + =2: Piecewise Parabolic Method (PPM) +!kind=default +!range= +sort-key=Panel-A31 +trigger= +type=integer + +[namelist:transport=ffsl_splitting] +!bounds=namelist:transport=profile_size +compulsory=true +description=Which horizontal splitting to use for consistent and conservative + =tracer transport with the FFSL scheme. SWIFT facilitates positivity + =but all steps use higher-order reconstructions. COSMIC does not + =facilitate positivity but can use lower-order reconstructions for + =inner steps. +fail-if= +help=The options are 1 = 'swift', 2 = 'cosmic' +!kind=default +length=: +sort-key=Panel-A04d +type=integer + +[namelist:transport=ffsl_unity_3d] +compulsory=true +description=Whether the unity transport field undergoes 3D transport, or reset + =the unity transport at each split transport step. +fail-if= +help=If true, FFSL transport is relative to a 3D unity transport, rather than + =a resetting the unity transport at each step. +!kind=default +sort-key=Panel-A26 +trigger= +type=logical + +[namelist:transport=ffsl_vertical_order] +!bounds=namelist:transport=profile_size +compulsory=true +description=Order of the vertical FFSL scheme. +fail-if= +help=The order of the vertical FFSL scheme. This is the outer order + =for 3D FFSL, and the only order for dimensionally split FFSL. + =0: Piecewise Constant Method (PCM) + =1: Nirvana Method + =2: Piecewise Parabolic Method (PPM) +!kind=default +length=: +sort-key=Panel-A32 +type=integer + +[namelist:transport=field_names] +!bounds=namelist:transport=profile_size +compulsory=true +description=Names of advected fields / groups +fail-if=len(this) != namelist:transport=profile_size ; +help= +length=: +sort-key=Panel-A04 +!string_length=default +type=character + +[namelist:transport=fv_horizontal_order] +compulsory=true +description=Order of polynomials to use for the horizontal reconstruction + =in the MoL scheme +fail-if= +help=?????? + =?????? +!kind=default +!range= +sort-key=Panel-A03 +trigger= +type=integer + +[namelist:transport=fv_vertical_order] +compulsory=true +description=Order of polynomials to use for the vertical reconstruction + =in the MoL scheme +fail-if= +help=?????? + =?????? +!kind=default +!range= +sort-key=Panel-A04 +# This option should only be triggered if transport scheme is method_of_lines +trigger= +type=integer + +[namelist:transport=horizontal_method] +!bounds=namelist:transport=profile_size +compulsory=true +description=Horizontal method to use +fail-if= +help=This should be an enumerated types but enumerated type arrays are not supported. + = The options are 0 = 'null', 1 = 'mol', 2 = 'ffsl', 3 = 'sl' +!kind=default +length=: +sort-key=Panel-A04b +type=integer + +[namelist:transport=horizontal_monotone] +!bounds=namelist:transport=profile_size +compulsory=true +description=monotone scheme used for horizontal transport +fail-if=(this == 2 or this == 3) and namelist:transport=horizontal_method != 1 + =(this == 4 or this == 5 or this == 6 or this == 7) and namelist:transport=horizontal_method == 1 +help=The options are + = 1 = 'none (no monotonicity)', + = 2 = 'clipping (only for MOL)', + = 3 = 'koren (only for MOL)', + = 4 = 'sl_strict (only for FFSL/SL)', + = 5 = 'sl_relaxed (only for FFSL)', + = 6 = 'positive (only for FFSL/SL)', + = 7 = 'quasi-monotone (only for FFSL), assume positivity limiter unless transport=min_value is set' +!kind=default +length=: +sort-key=Panel-A04d +type=integer + +[namelist:transport=log_space] +!bounds=namelist:transport=profile_size +compulsory=true +description=Perform vertical interpolation in log space +help= +!kind=default +length=: +sort-key=Panel-A04c +type=logical + +[namelist:transport=max_vert_cfl_calc] +compulsory=true +description=Method to compute the maximum vertical CFL used for substepping the MoL scheme. +!enumeration=true +fail-if=this=="'dep_point'" and namelist:transport=calculate_detj=="'averaged'" +help=uniform : sets CFL=w dt/dz. This does not take into account the + = vertical grid spacing away from the cell (i.e. it assumes + = a uniform vertical extrusion). + =departure point: uses the vertical departure point calculation to set + = the maximum CFL. The departure point is calculated using + = the physical vertical grid and so the vertical grid spacing + = is taken into account. +sort-key=Panel-A01 +value-titles=uniform, departure point +values='uniform', 'dep_point' + +[namelist:transport=min_val_abs_tol] +compulsory=true +description=The flux limiter is stopped once the minimum field value exceeds the + =absolute tolerance specified here. +fail-if=this > 0.0 ; +help=The flux limiter will stop iterating once the minimum field value exceeds + =this value. Values must be negative. Values should be small compared with + =the typical field value. +range=-99999.99:0.0 +sort-key=Panel-A06 +type=real + +[namelist:transport=min_val_max_iterations] +compulsory=true +description=The maximum number of iterations to be performed by the flux limiter. +fail-if= +help=The flux limiter will be stopped once it has either given a field whose + =minimum exceeds the value specified by the min_val_abs_tol option, + =or once it has performed this many iterations. +!kind=default +sort-key=Panel-A06 +type=integer + +[namelist:transport=min_val_method] +compulsory=true +description=Method to use for the conservative positivity limiter. Applies to + =variables that are transported with the consistent or conservative + =form of the transport equation. Any variable which is only advected + =will be clipped to ensure positivity. +!enumeration=true +help=clipping: a simple, non-conservative clipping. + =iterative: uses an iterative flux limiting method, which limits fluxes + = outgoing from a cell, based on the incoming fluxes. As the + = incoming fluxes may be changed, a single iteration may not + = guarantee positivity. This method therefore iterates until the + = field is acceptably close to being positive, before sweeping up + = any remaining negative values. + =columnwise_fixer: clips negative values in a column, before rescaling the + = remaining positive values to ensure conservation of mass. +sort-key=Panel-A04a +trigger=namelist:transport=min_val_max_iterations: this == "'iterative'"; + =namelist:transport=min_val_abs_tol: this == "'iterative'"; +value-titles=Clipping, iterative, columnwise_fixer +values='clipping', 'iterative', 'columnwise_fixer' + +[namelist:transport=min_value] +!bounds=namelist:transport=profile_size +compulsory=true +description=The minimum value imposed for the transported field +help= +!kind=default +length=: +sort-key=Panel-A04c +type=real + +[namelist:transport=oned_reconstruction] +compulsory=true +description=Control use of 1D or 2D polynomial reconstruction of tracer fields + =for the method of lines advection scheme +fail-if= +help=Use 1D or 2D horizontal reconstruction +!kind=default +sort-key=Panel-A07 +# This option should only be triggered if transport scheme is method_of_lines +trigger= +type=logical + +[namelist:transport=operators] +compulsory=true +description=Use finite volume (lowest order only) or finite element + =operators to compute the spatial reconstruction in the mol scheme +!enumeration=true +fail-if=this=="'fv'" and (namelist:finite_element=element_order_h > 0 or namelist:finite_element=element_order_v > 0) +help=?????? + =?????? +sort-key=Panel-A02 +# This option should only be triggered if transport scheme is method_of_lines +trigger= +value-titles=Finite volume, Finite element +values='fv', 'fem' + +[namelist:transport=panel_edge_high_order] +compulsory=true +description=Whether to use high-order treatment of horizontal reconstructions at + =the edges of cubed-sphere panels, for whichever scheme is used to + =treat panel edges. If true, reconstructions will generally be cubic, + =whereas they will generally be linear if this is set to false. + =Cubic reconstructions will be more accurate but may require larger + =stencils. +fail-if= +help=This sets the order of the panel edge treatment. For each treatment, this + =does the following: + =Extended Mesh: If this is true, the remapping to the extended mesh uses + = cubic polynomials. If false, it uses linear polynomials. + =Special Edges: If this is true, the reconstruction of the special edges + = shifts the stencil by an extra point, which requires the + = model to use a greater halo depth. If false, the horizontal + = reconstruction drops by an order and no extra point is + = required. + =Remapping: If this is true, the remapping to the extended mesh uses + = cubic polynomials. If false, it uses linear polynomials. + = When performing redundant computations, this requires the + = halo depth (and the size of halo exchanges) to be increased. +!kind=default +sort-key=Panel-A05b +trigger= +type=logical + +[namelist:transport=panel_edge_treatment] +compulsory=true +description=Describes how horizontal field reconstructions are handled at the + =edges of cubed-sphere panels during transport. At these edges, the + =coordinate fields are discontinuous, which can lead to grid + =imprinting when performing a naive reconstruction. Several different + =options are implemented, with different properties. +!enumeration=true +fail-if= +help=The options are described as follows: + =None: No treatment of panel edges is applied, which can lead to + = grid imprinting. + =Extended Mesh: Reconstructions are performed on computational panels that + = extend beyond the normal boundaries at alpha/beta +/- pi/4. + = Reconstructions therefore occur in uniform alpha-beta space. + = This option performs well for the Method-of-Lines scheme + = (it is only relevant for the Koren monotonicity scheme or + = when using 1D reconstructions), but can be expensive when + = used with FFSL, where any part of a calculation that crosses + = a panel edge is performed on the "extended mesh". This + = breaks formal monotonicity properties. + =Special Edges: Only relevant to FFSL. Reconstructions do not span panel + = edges, and involve shifting the stencil so that the stencil + = lies on a single panel, and the reconstructed field is + = extrapolated. + =Remapping: Fields are also mapped to extended panels, like in the + = "extended mesh" option, but these are only used in the + = fractional part of FFSL flux calculations. This still obeys + = any desired conservation and monotonicity properties. +sort-key=Panel-A05 +value-titles=None, Extended Mesh, Special Edges, Remapping +values='none', 'extended_mesh', 'special_edges', 'remapping' + +[namelist:transport=profile_size] +compulsory=true +description=Number of transport schemes to define +help=Number of transport schemes to define +!kind=default +range=0:100 +sort-key=Panel-A02 +type=integer + +[namelist:transport=reversible] +!bounds=namelist:transport=profile_size +compulsory=true +description=Use a reversible transport scheme +help=Use Hermite polynomials rather than Lagrange polynomials for the + =reconstructions used in the vertical SL or MoL transport schemes. By + =using this polynomial, the reconstruction will be independent of the + =vertical velocity. When used with vertical MoL transport, this Hermite + =polynomial only appears in the final Runge-Kutta stage. + =This option must be set to .true. when using a reversible configuration of + =the FFSL scheme for vertical transport. +!kind=default +length=: +sort-key=Panel-A04c +type=logical + +[namelist:transport=runge_kutta_method] +compulsory=true +description=Runge Kutta method to use the MoL scheme +!enumeration=true +fail-if= +help=Runge-Kutta method to use for the method of lines + =transport scheme. A variety of Strong Stability Preserving (SSP) + =methods with different orders of accuracy and CFL limit + =are available along with a forward Euler method which should be + =used for explicit timestepping methods +ns=namelist/Job/Transport/runge kutta +sort-key=Panel-A01 +value-titles=Foward Euler, + =Strong Stability Preserving: Order-2, + =Strong Stability Preserving: Order-3, + =Strong Stability Preserving: Order-4, + =Strong Stability Preserving: Order-5 +values='forward_euler', 'ssp2', 'ssp3', 'ssp4', 'ssp5' + +[namelist:transport=scheme] +!bounds=namelist:transport=profile_size +compulsory=true +description=Transport scheme to use +fail-if= +help=This should be an enumerated types but enumerated type arrays are not supported. + = The options are 1 = 'mol', 2 = 'ffsl', 3 = 'split' +!kind=default +length=: +sort-key=Panel-A04b +type=integer + +[namelist:transport=si_outer_transport] +compulsory=true +description=Efficiency option to speed up transport in the first outer + =semi-implicit iteration. +!enumeration=true +fail-if= +help=none : do nothing to speed up transport + =advective : use semi-Lagrangian advective transport for the first outer + = transport + =no_mono : use no monotonicity for the first outer transport + =horizontal_sl: horizontal semi-Lagrangian transport for the first outer + = transport +sort-key=Panel-A01 +value-titles=None, Advective, No monotonicity, Horizontal SL +values='none', 'advective', 'no_mono', 'horizontal_sl' + +[namelist:transport=slice_order] +compulsory=false +description=Order of the polynomial used for the reconstruction in slice-remapping. +!enumeration=true +fail-if= +help=constant : Constant piecewise reconstruction + =linear : Linear piecewise reconstruction + =parabola : Parabolic piecewise reconstruction + =cubic : Cubic piecewise reconstruction +sort-key=Panel-A01 +value-titles=constant, linear, parabola, cubic +values='constant', 'linear', 'parabola','cubic' + +[namelist:transport=special_edges_monotone] +!bounds=namelist:transport=profile_size +compulsory=true +description=Monotone option used for horizontal transport at special edges +help=This monotone option is only applied to fluxes at cubed sphere panel + =edges when the special edge treatment is used with FFSL. The array length + =is equal to the 'profile_size', so that a different option can be used for + =each transported variable. The options are + = 0 = 'none (no monotonicity)', + = 1 = 'full (same as horizontal_monotone)', + = 2 = 'positive (enforces positivity)', +!kind=default +length=: +range=0:2 +sort-key=Panel-A04d +type=integer + +[namelist:transport=splitting] +!bounds=namelist:transport=profile_size +compulsory=true +description=Directional (horizontal-vertical) splitting to use. +fail-if= +help=This should be an enumerated types but enumerated type arrays are not yet + =implemented. + =The options are given as a sequence of H (horizontal) and V (vertical) + =letters. These are + =1: no splitting + =2: Strang VHV splitting (weights of 1/2, 1, 1/2) + =3: Strang HVH splitting (weights of 1/2, 1, 1/2) + =4: VH splitting (weights of 1, 1) + =5: HV splitting (weights of 1, 1) + =6: VHVHV splitting (weights of 1/3, 1/2, 1/3, 1/2, 1/3) + =7: VHVHV splitting (weights of 1/4, 1/2, 1/2, 1/2, 1/4) + =8: VHHV splitting (weights of 1/2, 1/2, 1/2, 1/2) + =Note that Strang VHV is the preferred efficient splitting for SWIFT. +!kind=default +length=: +sort-key=Panel-A04b +type=integer + +[namelist:transport=substep_transport] +compulsory=true +description=Turn on substepping of gungho transport for FFSL if certain + =conditions are broken. +!enumeration=true +fail-if=this != "'off'" and namelist:transport=cheap_update == ".true." +help=off : Do not substep gungho transport + =adaptive : Substep if the maximum Lipschitz number exceeds 1 or if + = the maximum Courant number exceeds the stencil extent + =two : Run with two substeps for transport - used for debugging only + =four : Run with four substeps for transport - used for debugging only +sort-key=Panel-A01 +value-titles=off, adaptive, two, four +values='off', 'adaptive', 'two', 'four' + +[namelist:transport=theta_dispersion_correction] +compulsory=true +description=Whether to use the correction to improve the dispersion relation + =when using conservative theta transport. +fail-if= +help=When transporting the potential temperature variable with a conservative + =transport scheme, care is needed to avoid polluting the dispersion of + =gravity waves. This switch turns on the correction to the horizontal fluxes + =of Thuburn 2022, which improves the dispersion. +!kind=default +sort-key=Panel-A01b +trigger= +type=logical + +[namelist:transport=theta_variable] +compulsory=true +description=Which potential temperature variable to transport. +!enumeration=true +fail-if= +help=dry : The dry potential temperature, "theta = T/Pi" + =virtual dry : The virtual dry potential temperature, + = "theta_{vd} = T/Pi*(1+m_v/eps)" + =moist : The moist potential temperature that is materially conserved + = in the absence of phase changes, + = "theta_{m} = T*(p/p_0)^{cpm/Rm}", where the exponent involves + = the moist gas constant and moist specific heat capacity. In + = the absence of moisture, this reverts to the dry variable. +sort-key=Panel-A24 +value-titles=dry, virtual dry, moist +values='dry', 'virtual_dry', 'moist' + +[namelist:transport=transport_ageofair] +compulsory=false +description=Option to transport age-of-air diagnostic. +fail-if= +!range=: +sort-key=Panel-A01 +type=logical + +[namelist:transport=use_density_predictor] +compulsory=true +description=DEPRECATED If set to true, then the divergence term will be included + =in the transport of density +fail-if= +help=Use predictor for density for improved stability of SI timestep +!kind=default +sort-key=Panel-A05 +type=logical + +[namelist:transport=vertical_method] +!bounds=namelist:transport=profile_size +compulsory=true +description=Method to use for vertical transport. If FFSL is used with a + =reversible reconstruction, then the reversible namelist option must + =also be set to true. +fail-if= +help=This should be an enumerated types but enumerated type arrays are not supported. + = The options are 0 = 'null', 1 = 'mol', 2 = 'ffsl', 3 = 'sl' +!kind=default +length=: +sort-key=Panel-A04b +type=integer + +[namelist:transport=vertical_monotone] +!bounds=namelist:transport=profile_size +compulsory=true +description=monotone scheme used for vertical transport +fail-if=(this == 2 or this == 3) and namelist:transport=vertical_method != 1 + =(this == 4 or this == 5 or this == 6 or this == 7) and namelist:transport=vertical_method == 1 +help=The options are + = 1 = 'none (no monotonicity)', + = 2 = 'clipping (only for MOL)', + = 3 = 'koren (only for MOL)', + = 4 = 'sl_strict (only for FFSL/SL)', + = 5 = 'sl_relaxed (only for FFSL/SL)', + = 6 = 'positive (only for FFSL)', + = 7 = 'quasi-monotone (only for FFSL with PPM), assume positivity limiter unless transport=min_value is set' +!kind=default +length=: +sort-key=Panel-A04e +type=integer + +[namelist:transport=vertical_monotone_order] +!bounds=namelist:transport=profile_size +compulsory=true +description=option (or order) of the monotone scheme for semi-Lagrangian vertical transport +help=The options are 1 = 'constant', 2 = 'linear', 3 = 'high' +!kind=default +length=: +sort-key=Panel-A04f +type=integer + +[namelist:transport=vertical_sl_order] +compulsory=false +description=Order of the polynomial used for the vertical semi-Lagrangian. +!enumeration=true +fail-if= +help=cubic : Cubic interpolation + =quintic : Quintic interpolation + =cubic_hermite : Cubic-Hermite interpolation + =linear : Linear interpolation +sort-key=Panel-A01 +value-titles=cubic, quintic, cubic_hermite, linear +values='cubic','quintic','cubic_hermite', 'linear' + +[namelist:transport=wind_mono_top] +compulsory=true +description=Whether to apply a monotonicity limiter to the vertical transport of + =wind components near the top of the atmosphere. +fail-if= +help=Applies the relaxed monotonicity limiter to the vertical transport of wind + =components for a number of layers at the top of the atmosphere (the + =number of layers is specified by the "wind_mono_top_depth" option). If + =monotonicity is already specified for the vertical wind transport, this + =does nothing. This is only applicable to the FFSL scheme, and for + =irreversible Nirvana reconstructions. +!kind=default +sort-key=Panel-A15 +trigger=namelist:transport=wind_mono_top_depth: this == ".true." +type=logical + +[namelist:transport=wind_mono_top_depth] +compulsory=true +description=The number of levels at the model top over which to apply the + =monotonicity limiter to the vertical transport of wind components. +fail-if=this < 0; + =this > namelist:extrusion=number_of_layers; +help= +!kind=default +sort-key=Panel-A15b +type=integer + +#============================================================================== +# IDEALISED FORCING OF WATER VAPOUR +#============================================================================== +[namelist:vapour_forcing] +compulsory=true +description=Settings for water vapour forcing +ns=namelist/Science/External Forcing/Vapour forcing +sort-key=B1 +title=Water vapour forcing + +[namelist:vapour_forcing=coordinate] +compulsory=true +description=Vertical coordinate for vapour tendency forcing +!enumeration=true +help=Vapour tendency forcing profiles may be specified with either height + =or pressure as the vertical coordinate. In both cases the coordinate + =information is entered using the heights array. + =Height: height in metres above sea-level. Values should be monotonically increasing. + =Pressure: pressure level in Pascals. Values should be monotonically decreasing. +!kind=default +ns=namelist/Science/External Forcing/Vapour forcing +sort-key=Panel-A04b +value-titles=Height, Pressure +values='height', 'pressure' + +[namelist:vapour_forcing=heights] +!bounds=namelist:vapour_forcing=number_heights +compulsory=true +description=Vapour tendency heights +fail-if=len(this) != namelist:vapour_forcing=number_heights +help=Heights for vapour tendency profile. If in ascending order, these are + =taken to be height in metres. Heights specified in descending order are + =taken to be pressure coordinate in Pascals. +!kind=default +length=: +ns=namelist/Science/External Forcing/Vapour forcing +sort-key=Panel-A04c +type=real + +[namelist:vapour_forcing=number_heights] +compulsory=true +description=Size of vapour tendency profile +help=Number of data points in the vapour tendency profile. +!kind=default +ns=namelist/Science/External Forcing/Vapour forcing +range=0:200 +sort-key=Panel-A04a +type=integer + +[namelist:vapour_forcing=number_times] +compulsory=true +description=Number of vapour tendency profile +help=Vapour tendency profiles at the times specified in + =the times array. +!kind=default +ns=namelist/Science/External Forcing/Vapour forcing +range=0:100 +sort-key=Panel-A04d +type=integer + +[namelist:vapour_forcing=profile_data] +!bounds=namelist:vapour_forcing=number_heights * namelist:vapour_forcing=number_times +compulsory=true +description=Temperature tendency data +fail-if=len(this) != namelist:vapour_forcing=number_heights * namelist:vapour_forcing=number_times +help=Water vapour mixing ratio tendency (kg/kg/s) +!kind=default +length=: +ns=namelist/Science/External Forcing/Vapour forcing +sort-key=Panel-A04e +type=real + +[namelist:vapour_forcing=times] +!bounds=namelist:vapour_forcing=number_times +compulsory=true +description=Vapour tendency times +fail-if=len(this) != namelist:vapour_forcing=number_times +help= +!kind=default +length=: +ns=namelist/Science/External Forcing/Vapour forcing +sort-key=Panel-A04f +type=real + +#============================================================================== +# IDEALISED FORCING - VERTICAL ADVECTION OF THETA, MV, MCL, U, V +#============================================================================== +[namelist:vertadvect] +compulsory=true +description=Settings for vertical advection forcing +ns=namelist/Science/External Forcing/Advection Forcing +sort-key=D1 +title=Vertical advection forcing + +[namelist:vertadvect=heights] +!bounds=namelist:vertadvect=number_heights +compulsory=true +description=Heights of points in vertical advection velocity profiles +fail-if=len(this) != namelist:vertadvect=number_heights +help=Heights for vertical advection wind profiles. If in ascending order, + =these are taken to be height in metres. Heights specified in descending + =order are taken to be pressure coordinate in Pascals. +!kind=default +length=: +ns=namelist/Science/External Forcing/Advection Forcing +sort-key=Panel-A05c +type=real + +[namelist:vertadvect=number_heights] +compulsory=true +description=Number of points in each vertical advection velocity profile +help= +!kind=default +ns=namelist/Science/External Forcing/Advection Forcing +range=0:200 +sort-key=Panel-A05a +type=integer + +[namelist:vertadvect=number_times] +compulsory=true +description=Number of vertical advection velocity profiles +help= +!kind=default +ns=namelist/Science/External Forcing/Advection Forcing +range=0:100 +sort-key=Panel-A05d +type=integer + +[namelist:vertadvect=profile_data_w] +!bounds=namelist:vertadvect=number_heights * namelist:vertadvect=number_times +compulsory=true +description=Vertical advection vertical velocity data +fail-if=len(this) != namelist:vertadvect=number_heights * namelist:vertadvect=number_times +help=Vertical Advection wind (m/s) +!kind=default +length=: +ns=namelist/Science/External Forcing/Advection Forcing +sort-key=Panel-A05d +type=real + +[namelist:vertadvect=times] +!bounds=namelist:vertadvect=number_times +compulsory=true +description=Timestamps (in seconds) of vertical advection profiles +help=Validity times (in seconds) of the vertical velocity profiles + =for idealised vertical advection forcing +!kind=default +length=: +ns=namelist/Science/External Forcing/Advection Forcing +sort-key=Panel-A05f +type=real + +#============================================================================== +# IDEALISED FORCING OF HORIZONTAL WIND COMPONENTS +#============================================================================== +[namelist:wind_forcing] +compulsory=true +description=Settings for wind forcing +ns=namelist/Science/External Forcing/Wind Forcing +sort-key=C1 +title=Horizontal wind forcing + +[namelist:wind_forcing=coordinate] +compulsory=true +description=Vertical coordinate for wind tendency forcing +!enumeration=true +help=Wind tendency forcing profiles may be specified with either height + =or pressure as the vertical coordinate. In both cases the coordinate + =information is entered using the heights array. + =Height: height in metres above sea-level. Values should be monotonically increasing. + =Pressure: pressure level in Pascals. Values should be monotonically decreasing. +!kind=default +ns=namelist/Science/External Forcing/Wind Forcing +sort-key=Panel-A01b +value-titles=Height, Pressure +values='height', 'pressure' + +[namelist:wind_forcing=heights] +!bounds=namelist:wind_forcing=number_heights +compulsory=true +description=Wind tendency heights +fail-if=len(this) != namelist:wind_forcing=number_heights +help=Heights for wind tendency profile. If in ascending order, these are + =taken to be height in metres. Heights specified in descending order are + =taken to be pressure coordinate in Pascals. +!kind=default +length=: +ns=namelist/Science/External Forcing/Wind Forcing +sort-key=Panel-A01c +type=real + +[namelist:wind_forcing=number_heights] +compulsory=true +description=Size of wind tendency profile +help=Number of data points in the wind tendency profile. +!kind=default +ns=namelist/Science/External Forcing/Wind Forcing +range=0:200 +sort-key=Panel-A01a +type=integer + +[namelist:wind_forcing=number_times] +compulsory=true +description=Number of wind tendency profile +help=Wind tendency profiles at the times specified in + =the times array. +!kind=default +ns=namelist/Science/External Forcing/Wind Forcing +range=0:100 +sort-key=Panel-A01a +type=integer + +[namelist:wind_forcing=profile_data_u] +!bounds=namelist:wind_forcing=number_heights * namelist:wind_forcing=number_times +compulsory=true +description=Wind tendency data +fail-if=len(this) != namelist:wind_forcing=number_heights * namelist:wind_forcing=number_times +help=Wind tendency for u-component of wind (m/s/s) +!kind=default +length=: +ns=namelist/Science/External Forcing/Wind Forcing +sort-key=Panel-A01d +type=real + +[namelist:wind_forcing=profile_data_v] +!bounds=namelist:wind_forcing=number_heights * namelist:wind_forcing=number_times +compulsory=true +description=Wind tendency data +fail-if=len(this) != namelist:wind_forcing=number_heights * namelist:wind_forcing=number_times +help=Wind tendency for v-component of wind (m/s/s) +!kind=default +length=: +ns=namelist/Science/External Forcing/Wind Forcing +sort-key=Panel-A01d +type=real + +[namelist:wind_forcing=times] +!bounds=namelist:wind_forcing=number_times +compulsory=true +description=Wind tendency times +fail-if=len(this) != namelist:wind_forcing=number_times +help= +!kind=default +length=: +ns=namelist/Science/External Forcing/Wind Forcing +sort-key=Panel-A01c +type=real + +[physics mapping] +ns=namelist/Science/Physics mapping +sort-key=C + +[planet properties] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Model/Planet/Properties +sort-key=Section-A02 + +[run configuration] +compulsory=false +ns=namelist +title=Run Task Settings + +[runge-kutta] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Job/Timestepping/runge kutta +sort-key=Section-A01 +title=Runge-Kutta + +#============================================================================== +# SCIENCE CONFIGURATION +#============================================================================== +[science] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Science +sort-key=Section-A03 + +[semi-implicit] +compulsory=false +description=?????? +help=?????? + =?????? +ns=namelist/Job/Timestepping/semi-implicit +sort-key=Section-A02 +title=Semi-implicit + +[timestep placements] +ns=namelist/Science/Timestep placement +sort-key=D diff --git a/science/gungho/source/algorithm/core_dynamics/derive_exner_from_eos_alg_mod.x90 b/science/gungho/source/algorithm/core_dynamics/derive_exner_from_eos_alg_mod.x90 index 522066e02..ca07eb35c 100644 --- a/science/gungho/source/algorithm/core_dynamics/derive_exner_from_eos_alg_mod.x90 +++ b/science/gungho/source/algorithm/core_dynamics/derive_exner_from_eos_alg_mod.x90 @@ -12,8 +12,8 @@ module derive_exner_from_eos_alg_mod use field_mod, only: field_type use derived_config_mod, only: bundle_size use field_indices_mod, only: igh_p, igh_d, igh_t - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use log_mod, only: log_event, & LOG_LEVEL_ERROR @@ -56,8 +56,9 @@ contains type( quadrature_xyoz_type ), pointer :: qr => null() type( mesh_type ), pointer :: mesh => null() + integer( tik ) :: id - if ( subroutine_timers ) call timer('exner_from_eos') + if ( LPROF ) call start_timing( id, 'dynamics.exner_from_eos' ) mesh => state(igh_p)%get_mesh() @@ -83,7 +84,7 @@ contains nullify( m3_inv, chi, mesh, & panel_id, qr ) - if ( subroutine_timers ) call timer('exner_from_eos') + if ( LPROF ) call stop_timing( id, 'dynamics.exner_from_eos' ) end subroutine derive_exner_from_eos diff --git a/science/gungho/source/algorithm/core_dynamics/intermesh_mappings_alg_mod.x90 b/science/gungho/source/algorithm/core_dynamics/intermesh_mappings_alg_mod.x90 index 19f953a48..12e8ac5e3 100644 --- a/science/gungho/source/algorithm/core_dynamics/intermesh_mappings_alg_mod.x90 +++ b/science/gungho/source/algorithm/core_dynamics/intermesh_mappings_alg_mod.x90 @@ -341,10 +341,9 @@ contains end if else - if ( present(lowest_order_flag) .and. lowest_order_flag ) then - recovery_order_arg = recovery_order_constant - else - recovery_order_arg = recovery_order + recovery_order_arg = recovery_order + if (present(lowest_order_flag)) then + if (lowest_order_flag) recovery_order_arg = recovery_order_constant end if if (ndata > 1) then if (present(source_mask)) then diff --git a/science/gungho/source/algorithm/core_dynamics/rhs_alg_mod.x90 b/science/gungho/source/algorithm/core_dynamics/rhs_alg_mod.x90 index f78729ba9..f8289b094 100644 --- a/science/gungho/source/algorithm/core_dynamics/rhs_alg_mod.x90 +++ b/science/gungho/source/algorithm/core_dynamics/rhs_alg_mod.x90 @@ -43,8 +43,8 @@ module rhs_alg_mod use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type use derived_config_mod, only: bundle_size use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use rhs_project_eos_kernel_mod, only: rhs_project_eos_kernel_type use rhs_sample_eos_kernel_mod, only: rhs_sample_eos_kernel_type use moist_dyn_mod, only: num_moist_factors, gas_law @@ -156,6 +156,8 @@ contains type(field_type) :: rhs_u integer(kind=i_def) :: mesh_id type(field_type) :: theta_v + integer(tik) :: id + ! For continuous fields the default looping depth is to the depth 1 halo ! and so for any fields that are accessed with a stencil the halo_depth @@ -163,7 +165,7 @@ contains integer(kind=i_def), parameter :: req_stencil_depth = 1 integer(kind=i_def), parameter :: req_halo_depth = req_stencil_depth + 1 - if ( subroutine_timers ) call timer('rhs_alg') + if ( LPROF ) call start_timing( id, 'dynamics.rhs_alg' ) mesh_id = base_state(igh_u)%get_mesh_id() @@ -233,7 +235,7 @@ contains geopotential, u, theta, rho, exner, & u_base, theta_base, rho_base ) - if ( subroutine_timers ) call timer('rhs_alg') + if ( LPROF ) call stop_timing( id, 'dynamics.rhs_alg' ) end subroutine rhs_default_alg @@ -283,6 +285,7 @@ contains integer(kind=i_def) :: element_order_v type(field_type) :: rhs_adv type(field_type) :: exner_big_halo + integer(tik) :: id ! For continuous fields the default looping depth is to the depth 1 halo ! and so for any fields that are accessed with a stencil the halo_depth @@ -290,7 +293,7 @@ contains integer(kind=i_def), parameter :: req_stencil_depth = 1 integer(kind=i_def), parameter :: req_halo_depth = req_stencil_depth + 1 - if ( subroutine_timers ) call timer('rhs_alg') + if ( LPROF ) call start_timing( id, 'dynamics.rhs_alg' ) mesh_id = base_state(igh_u)%get_mesh_id() @@ -424,7 +427,7 @@ contains geopotential, u, theta, rho, exner, & mesh, reference_element ) - if ( subroutine_timers ) call timer('rhs_alg') + if ( LPROF ) call stop_timing( id, 'dynamics.rhs_alg' ) end subroutine rhs_general_alg diff --git a/science/gungho/source/algorithm/diagnostics/ageofair_alg_mod.x90 b/science/gungho/source/algorithm/diagnostics/ageofair_alg_mod.x90 index 24dfcc57e..c6d335dd3 100644 --- a/science/gungho/source/algorithm/diagnostics/ageofair_alg_mod.x90 +++ b/science/gungho/source/algorithm/diagnostics/ageofair_alg_mod.x90 @@ -10,8 +10,8 @@ module ageofair_alg_mod use clock_mod, only: clock_type use constants_mod, only: r_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use ageofair_kernel_mod, only: ageofair_kernel_type use transport_config_mod, only: ageofair_reset_level @@ -50,8 +50,9 @@ contains type(field_type) :: ones real(r_def) :: dt + integer(tik) :: id - if ( subroutine_timers ) call timer( 'ageofair_advection_alg' ) + if ( LPROF ) call start_timing( id, 'dynamics.ageofair' ) dt = real(clock%get_seconds_per_step(), r_def) @@ -62,7 +63,7 @@ contains ! Set levels nearest the surface to be zero in ageofair field ageofair_kernel_type(ageofair,ageofair_reset_level) ) - if ( subroutine_timers ) call timer( 'ageofair_advection_alg' ) + if ( LPROF ) call stop_timing( id, 'dynamics.ageofair' ) end subroutine ageofair_update diff --git a/science/gungho/source/algorithm/diagnostics/compute_total_energy_alg_mod.x90 b/science/gungho/source/algorithm/diagnostics/compute_total_energy_alg_mod.x90 index 4651e9a47..78e1279fc 100644 --- a/science/gungho/source/algorithm/diagnostics/compute_total_energy_alg_mod.x90 +++ b/science/gungho/source/algorithm/diagnostics/compute_total_energy_alg_mod.x90 @@ -26,7 +26,6 @@ module compute_total_energy_alg_mod get_coordinates, & get_panel_id, & get_da_msl_proj - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_DEBUG, & @@ -38,7 +37,7 @@ module compute_total_energy_alg_mod use planet_config_mod, only: cv, gravity use quadrature_xyoz_mod, only: quadrature_xyoz_type use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -122,8 +121,9 @@ contains real( kind=r_def ) :: surface_geopotential integer(kind=i_def) :: nqp_h_exact, nqp_v_exact integer(kind=i_def) :: element_order_h, element_order_v + integer(tik) :: id - if ( subroutine_timers ) call timer( "compute_total_energy" ) + if ( LPROF ) call start_timing( id, 'diags.total_energy' ) geopotential => get_geopotential( mesh%get_id() ) surface_geopotential = planet_radius*gravity @@ -245,7 +245,7 @@ contains nullify( geopotential ) - if ( subroutine_timers ) call timer( "compute_total_energy" ) + if ( LPROF ) call stop_timing( id, 'diags.total_energy' ) end subroutine compute_total_energy_alg diff --git a/science/gungho/source/algorithm/diagnostics/conservation_algorithm_mod.x90 b/science/gungho/source/algorithm/diagnostics/conservation_algorithm_mod.x90 index e9ba657e6..a910cd0f6 100644 --- a/science/gungho/source/algorithm/diagnostics/conservation_algorithm_mod.x90 +++ b/science/gungho/source/algorithm/diagnostics/conservation_algorithm_mod.x90 @@ -31,11 +31,11 @@ module conservation_algorithm_mod use dycore_constants_mod, only: get_geopotential use sci_geometric_constants_mod, only: get_coordinates, & get_panel_id - use io_config_mod, only: subroutine_timers, use_xios_io + use io_config_mod, only: use_xios_io use planet_config_mod, only: scaled_omega, cv, gravity use mr_indices_mod, only: nummr - use timer_mod, only: timer - + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use initialise_diagnostics_mod, only: diagnostic_to_be_sampled use extrusion_config_mod, only: planet_radius @@ -90,10 +90,11 @@ contains total_entropy_dyn_dry, & surface_geopotential type(mesh_type), pointer :: mesh => null() + integer(tik) :: id procedure(write_interface), pointer :: write_behaviour => null() - if ( subroutine_timers ) call timer('conservation_alg') + if ( LPROF ) call start_timing( id, 'diags.conservation' ) element_order_h = rho%get_element_order_h() element_order_v = rho%get_element_order_v() @@ -212,7 +213,7 @@ contains nullify( chi, panel_id, w3_fs, mesh ) nullify ( write_behaviour ) - if ( subroutine_timers ) call timer('conservation_alg') + if ( LPROF ) call stop_timing( id, 'diags.conservation' ) end subroutine conservation_algorithm diff --git a/science/gungho/source/algorithm/diagnostics/moisture_conservation_alg_mod.x90 b/science/gungho/source/algorithm/diagnostics/moisture_conservation_alg_mod.x90 index 31afc1291..48ab982ca 100644 --- a/science/gungho/source/algorithm/diagnostics/moisture_conservation_alg_mod.x90 +++ b/science/gungho/source/algorithm/diagnostics/moisture_conservation_alg_mod.x90 @@ -26,8 +26,8 @@ module moisture_conservation_alg_mod use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type use sci_geometric_constants_mod, only: get_coordinates, & get_panel_id - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -76,8 +76,9 @@ contains type(mesh_type), pointer :: mesh => null() type(mesh_type), pointer :: shifted_mesh => null() + integer(tik) :: id - if ( subroutine_timers ) call timer('moisture_conservation_alg') + if ( LPROF ) call start_timing( id, 'diags.moisture_conservation' ) element_order_h = rho_d%get_element_order_h() element_order_v = rho_d%get_element_order_v() @@ -126,7 +127,7 @@ contains nullify( chi, panel_id, w3_fs, w3_fs, mesh, shifted_mesh, chi_shifted ) - if ( subroutine_timers ) call timer('moisture_conservation_alg') + if ( LPROF ) call stop_timing( id, 'diags.moisture_conservation' ) end subroutine moisture_conservation_alg diff --git a/science/gungho/source/algorithm/diagnostics/moisture_fluxes_alg_mod.x90 b/science/gungho/source/algorithm/diagnostics/moisture_fluxes_alg_mod.x90 index 0a311f1dd..77c216e35 100644 --- a/science/gungho/source/algorithm/diagnostics/moisture_fluxes_alg_mod.x90 +++ b/science/gungho/source/algorithm/diagnostics/moisture_fluxes_alg_mod.x90 @@ -19,8 +19,7 @@ module moisture_fluxes_alg_mod use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_INFO - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use sci_multi_extract_kernel_mod, & only: multi_extract_kernel_type @@ -77,9 +76,9 @@ contains real(kind=r_def) :: ls_rain_mass, ls_snow_mass, ls_graup_mass real(kind=r_def) :: conv_rain_mass, conv_snow_mass integer(kind=i_def) :: mesh + integer(tik) :: id - - if ( subroutine_timers ) call timer('moisture_fluxes_alg') + if ( LPROF ) call start_timing( id, 'diags.moisture_fluxes' ) mesh = area%get_mesh_id() call microphysics_fields%get_field('ls_rain', ls_rain) @@ -164,7 +163,7 @@ contains nullify( fs_2d ) nullify( ls_rain, ls_snow, ls_graup, conv_rain, conv_snow, moist_flux_bl ) - if ( subroutine_timers ) call timer('moisture_fluxes_alg') + if ( LPROF ) call stop_timing( id, 'diags.moisture_fluxes' ) end subroutine moisture_fluxes_alg diff --git a/science/gungho/source/algorithm/diagnostics/si_diagnostics_mod.x90 b/science/gungho/source/algorithm/diagnostics/si_diagnostics_mod.x90 index a96fd0d99..7e865b2bb 100644 --- a/science/gungho/source/algorithm/diagnostics/si_diagnostics_mod.x90 +++ b/science/gungho/source/algorithm/diagnostics/si_diagnostics_mod.x90 @@ -22,8 +22,7 @@ module si_diagnostics_mod stochastic_physics_placement_fast use physics_mappings_alg_mod, only: map_physics_winds use mr_indices_mod, only: nummr, imr_v, imr_cl, imr_ci, imr_s - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field @@ -78,8 +77,9 @@ contains type(field_type), pointer :: exner_wth_n logical(l_def) :: ignore + integer(tik) :: id - if ( subroutine_timers ) call timer ("si_diagnostics") + if ( LPROF ) call start_timing( id, 'diags.dynamics' ) ! Slow physics timestep theta increments ! Difference between state at time step n (X_n) and X_after_slow @@ -237,7 +237,7 @@ contains if (dw_solv_flag) call dw_solv%write_field() end if - if ( subroutine_timers ) call timer ("si_diagnostics") + if ( LPROF ) call stop_timing( id, 'diags.dynamics' ) end subroutine output_diags_for_si diff --git a/science/gungho/source/algorithm/diffusion/leonard_term_alg_mod.x90 b/science/gungho/source/algorithm/diffusion/leonard_term_alg_mod.x90 index c9174a68e..8d622f535 100644 --- a/science/gungho/source/algorithm/diffusion/leonard_term_alg_mod.x90 +++ b/science/gungho/source/algorithm/diffusion/leonard_term_alg_mod.x90 @@ -21,8 +21,7 @@ module leonard_term_alg_mod use mixing_config_mod, only: leonard_kl - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use log_mod, only: log_event, LOG_LEVEL_INFO use model_clock_mod, only: model_clock_type @@ -94,6 +93,8 @@ subroutine leonard_term_alg(mt_inc_leonard, thetal_inc_leonard, & ! local variables integer(kind=i_def) :: mesh_id integer(kind=i_def), parameter :: stencil_depth = 1 + integer(tik) :: id + ! Leonard term parameter type( field_type ) :: kl ! liquid + ice water potential temperature @@ -103,7 +104,7 @@ subroutine leonard_term_alg(mt_inc_leonard, thetal_inc_leonard, & ! w increment type( field_type ) :: vel_w2v_inc_leonard - if ( subroutine_timers ) call timer("leonard_term_alg") + if ( LPROF ) call start_timing( id, 'leonard_term' ) mesh_id = theta%get_mesh_id() @@ -221,7 +222,7 @@ subroutine leonard_term_alg(mt_inc_leonard, thetal_inc_leonard, & nullify( height_w1, height_w2, height_w3, height_wth ) - if ( subroutine_timers ) call timer("leonard_term_alg") + if ( LPROF ) call stop_timing( id, 'leonard_term' ) end subroutine leonard_term_alg diff --git a/science/gungho/source/algorithm/diffusion/smagorinsky_alg_mod.x90 b/science/gungho/source/algorithm/diffusion/smagorinsky_alg_mod.x90 index d40e14ab7..c66bf5883 100644 --- a/science/gungho/source/algorithm/diffusion/smagorinsky_alg_mod.x90 +++ b/science/gungho/source/algorithm/diffusion/smagorinsky_alg_mod.x90 @@ -25,9 +25,8 @@ module smagorinsky_alg_mod use log_mod, only: log_event, & LOG_LEVEL_INFO use mesh_mod, only: mesh_type - use io_config_mod, only: subroutine_timers, & - write_conservation_diag - use timer_mod, only: timer + use io_config_mod, only: write_conservation_diag + use timing_mod, only: start_timing, stop_timing, tik, LPROF use moisture_conservation_alg_mod, & only: moisture_conservation_alg use sci_geometric_constants_mod, & @@ -91,8 +90,9 @@ subroutine smagorinsky_alg(dtheta_io, du_io, mr, theta, u, & logical :: use_moisture real( r_def ) :: one_third + integer(tik) :: id - if ( subroutine_timers ) call timer("smagorinsky_alg") + if ( LPROF ) call start_timing( id, 'smagorinsky' ) call log_event( 'Applying Smagorinsky mixing', LOG_LEVEL_INFO ) @@ -231,7 +231,7 @@ subroutine smagorinsky_alg(dtheta_io, du_io, mr, theta, u, & nullify( height_w1, height_w2 ) - if ( subroutine_timers ) call timer("smagorinsky_alg") + if ( LPROF ) call stop_timing( id, 'smagorinsky' ) end subroutine smagorinsky_alg diff --git a/science/gungho/source/algorithm/limited_area/init_gungho_lbcs_alg_mod.x90 b/science/gungho/source/algorithm/limited_area/init_gungho_lbcs_alg_mod.x90 index 24391689a..38ba51747 100644 --- a/science/gungho/source/algorithm/limited_area/init_gungho_lbcs_alg_mod.x90 +++ b/science/gungho/source/algorithm/limited_area/init_gungho_lbcs_alg_mod.x90 @@ -37,7 +37,8 @@ module init_gungho_lbcs_alg_mod use linked_list_mod, only: linked_list_type use mr_indices_mod, only: nummr, & mr_names - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use masked_minmax_alg_mod, only: log_field_masked_minmax implicit none @@ -167,16 +168,12 @@ module init_gungho_lbcs_alg_mod type(linked_list_type), intent(in) :: lbc_times_list class(model_clock_type), intent(in) :: clock type(field_type), pointer :: lbc_v_u + integer(tik) :: id - type(namelist_type), pointer :: io_nml type(namelist_type), pointer :: initialization_nml - logical(l_def) :: subroutine_timers integer(i_def) :: lbc_option - io_nml => configuration%get_namelist('io') - call io_nml%get_value( 'subroutine_timers', subroutine_timers ) - - if ( subroutine_timers ) call timer('init_lbcs') + if ( LPROF ) call start_timing( id, 'init_lbcs' ) nullify(lbc_v_u) @@ -209,7 +206,7 @@ module init_gungho_lbcs_alg_mod end if - if ( subroutine_timers ) call timer('init_lbcs') + if ( LPROF ) call stop_timing( id, 'init_lbcs' ) end subroutine init_lbcs_file_alg @@ -230,16 +227,12 @@ module init_gungho_lbcs_alg_mod type(linked_list_type), intent(in) :: lbc_times_list class(model_clock_type), intent(in) :: clock type(field_type), pointer :: lbc_v_u + integer(tik) :: id - type(namelist_type), pointer :: io_nml type(namelist_type), pointer :: initialization_nml - logical(l_def) :: subroutine_timers integer(i_def) :: lbc_option - io_nml => configuration%get_namelist('io') - call io_nml%get_value( 'subroutine_timers', subroutine_timers ) - - if ( subroutine_timers ) call timer('update_lbcs') + if ( LPROF ) call start_timing( id, 'update_lbcs' ) nullify(lbc_v_u) @@ -267,7 +260,7 @@ module init_gungho_lbcs_alg_mod ! Define boundary_u_driving call define_boundary_u( configuration, lbc_fields ) - if ( subroutine_timers ) call timer('update_lbcs') + if ( LPROF ) call stop_timing( id, 'update_lbcs' ) end subroutine update_lbcs_file_alg diff --git a/science/gungho/source/algorithm/physics/calc_phys_predictors_alg_mod.x90 b/science/gungho/source/algorithm/physics/calc_phys_predictors_alg_mod.x90 index 9a5d3c211..c0f5dd21b 100644 --- a/science/gungho/source/algorithm/physics/calc_phys_predictors_alg_mod.x90 +++ b/science/gungho/source/algorithm/physics/calc_phys_predictors_alg_mod.x90 @@ -22,8 +22,7 @@ module calc_phys_predictors_alg_mod use sci_hori_mass_matrix_solver_alg_mod, & only: hori_mass_matrix_solver_alg - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use limited_area_lbc_alg_mod, only: overwrite_blending_zone use boundaries_config_mod, only: limited_area, transport_boundary_depth @@ -76,8 +75,9 @@ subroutine calc_phys_predictors_alg( derived_fields, rhs_np1, rhs_adv, & type( field_type ), pointer :: lbc_theta => null() type( field_type ) :: du, dtheta, rhsu_np1, w_in_w3_star + integer( tik ) :: id - if ( subroutine_timers ) call timer("calc_phys_predictors") + if ( LPROF ) call start_timing( id, 'dynamics.phys_predictors' ) call derived_fields%get_field('theta_star', theta_star) call derived_fields%get_field('u_star', u_star) @@ -137,7 +137,7 @@ subroutine calc_phys_predictors_alg( derived_fields, rhs_np1, rhs_adv, & u_star) call w_in_w3_star%field_final() - if ( subroutine_timers ) call timer("calc_phys_predictors") + if ( LPROF ) call stop_timing( id, 'dynamics.phys_predictors' ) end subroutine calc_phys_predictors_alg diff --git a/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 b/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 index 1a0eb304d..a5dc88e87 100644 --- a/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 +++ b/science/gungho/source/algorithm/physics/external_forcing_alg_mod.X90 @@ -59,8 +59,7 @@ module external_forcing_alg_mod get_dx_at_w2 use mesh_mod, only: mesh_type use mr_indices_mod, only: nummr - use io_config_mod, only: subroutine_timers, write_diag, & - use_xios_io + use io_config_mod, only: write_diag, use_xios_io use planet_config_mod, only: kappa use section_choice_config_mod, only: cloud, cloud_um use cloud_config_mod, only: scheme, scheme_pc2 @@ -75,7 +74,8 @@ module external_forcing_alg_mod use vapour_forcing_profile_alg_mod, only: vapour_forcing_profile_alg use wind_forcing_profile_alg_mod, only: wind_forcing_profile_alg - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use w2_filter_alg_mod, only: w2_filter_alg @@ -153,8 +153,9 @@ contains type( mesh_type ), pointer :: mesh => null() procedure(write_interface), pointer :: write_behaviour => null() + integer(tik) :: id - if ( subroutine_timers ) call timer("external_forcing_alg") + if ( LPROF ) call start_timing( id, 'external_forcing' ) mesh => theta%get_mesh() height_wth => get_height_fv( Wtheta, mesh%get_id() ) @@ -450,6 +451,7 @@ contains end if #endif + if ( LPROF ) call stop_timing( id, 'external_forcing' ) ! ! Write out diagnostics (if available) ! @@ -457,9 +459,6 @@ contains call write_forcing_diagnostics(du_forcing=du_forcing, output_wind_inc=wind_forcing_done) end if - - if ( subroutine_timers ) call timer("external_forcing_alg") - end subroutine external_forcing_alg end module external_forcing_alg_mod diff --git a/science/gungho/source/algorithm/physics/fast_physics_alg_mod.X90 b/science/gungho/source/algorithm/physics/fast_physics_alg_mod.X90 index 34bc852f4..851921548 100644 --- a/science/gungho/source/algorithm/physics/fast_physics_alg_mod.X90 +++ b/science/gungho/source/algorithm/physics/fast_physics_alg_mod.X90 @@ -24,9 +24,8 @@ module fast_physics_alg_mod use log_mod, only: LOG_LEVEL_INFO, LOG_LEVEL_ERROR, log_event, & log_scratch_space use print_field_stats_alg_mod, only: print_field_stats_alg - use io_config_mod, only: subroutine_timers, & - write_conservation_diag - use timer_mod, only: timer + use io_config_mod, only: write_conservation_diag + use timing_mod, only: start_timing, stop_timing, tik, LPROF use physics_config_mod, only: blayer_placement, blayer_placement_fast, & convection_placement, & @@ -201,8 +200,9 @@ contains real( kind=r_def ) :: Rv, cpv, cl integer(i_def) :: i_mr + integer(tik) :: id - if ( subroutine_timers ) call timer("fast_physics") + if ( LPROF ) call start_timing( id, 'fast_physics' ) use_moisture = ( moisture_formulation /= moisture_formulation_dry ) @@ -411,7 +411,7 @@ contains call moisture_conservation_alg( rho, mr, 'After fast' ) end if - if ( subroutine_timers ) call timer("fast_physics") + if ( LPROF ) call stop_timing( id, 'fast_physics' ) end subroutine fast_physics diff --git a/science/gungho/source/algorithm/physics/map_fd_to_prognostics_alg_mod.x90 b/science/gungho/source/algorithm/physics/map_fd_to_prognostics_alg_mod.x90 index 7c006b9f1..8f81cc672 100644 --- a/science/gungho/source/algorithm/physics/map_fd_to_prognostics_alg_mod.x90 +++ b/science/gungho/source/algorithm/physics/map_fd_to_prognostics_alg_mod.x90 @@ -45,7 +45,6 @@ module map_fd_to_prognostics_alg_mod get_geopotential use fs_continuity_mod, only: W3, W2, W2broken, Wtheta use sci_sort_ref_kernel_mod, only: sort_ref_kernel_type - use timer_mod, only: timer use combine_w2_field_kernel_mod, only: combine_w2_field_kernel_type use idealised_config_mod, only: perturb_init, & perturb_magnitude @@ -62,7 +61,6 @@ module map_fd_to_prognostics_alg_mod topology_fully_periodic use formulation_config_mod, only: rotating, shallow use finite_element_config_mod, only: coord_system, coord_system_native - use io_config_mod, only: subroutine_timers use physics_config_mod, only: sample_physics_winds, & sample_physics_winds_correction use planet_config_mod, only: gravity, p_zero, kappa, rd, cp @@ -227,9 +225,10 @@ contains use matrix_vector_kernel_mod, only: matrix_vector_kernel_type use sci_average_w2b_to_w2_kernel_mod, & only: average_w2b_to_w2_kernel_type - use sci_w3_to_w2_average_kernel_mod, only: w3_to_w2_average_kernel_type use sci_w3_to_w2_correction_kernel_mod, & only: w3_to_w2_correction_kernel_type + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -239,6 +238,8 @@ contains type( field_type ) :: r_u type( field_type ) :: u_broken type( field_type ) :: u_lat_w2, u_lon_w2, u_up_w2 + type( field_type ) :: u_lat_large, u_lon_large + type( field_type ) :: u_correction type( field_type ), pointer :: rmultiplicity_w2 type( field_type ), pointer :: displacement type( field_type ), pointer :: chi(:) @@ -246,52 +247,17 @@ contains type( operator_type ), pointer :: u_lon_map type( operator_type ), pointer :: u_lat_map type( operator_type ), pointer :: u_up_map + type( function_space_type ), pointer :: w2_fs type( function_space_type ), pointer :: w2b_fs type( mesh_type ), pointer :: mesh + integer(tik) :: id - if ( subroutine_timers ) call timer("set_wind") + if ( LPROF ) call start_timing( id, 'mappings.set_wind' ) mesh => u%get_mesh() - if (sample_physics_winds .and. sample_physics_winds_correction) then - - chi => get_coordinates(mesh%get_id()) - rmultiplicity_w2 => get_rmultiplicity_fv(W2, mesh%get_id()) - panel_id => get_panel_id(mesh%get_id()) - call u_lon_w2%initialise( u%get_function_space() ) - call u_lat_w2%initialise( u%get_function_space() ) - call u_up_w2%initialise( u%get_function_space() ) - - call invoke( setval_c(u_lon_w2, 0.0_r_def), & - setval_c(u_lat_w2, 0.0_r_def), & - setval_c(u_up_w2, 0.0_r_def), & - w3_to_w2_average_kernel_type(u_lon_w2, u_lon, & - rmultiplicity_w2), & - w3_to_w2_average_kernel_type(u_lat_w2, u_lat, & - rmultiplicity_w2), & - w3_to_w2_average_kernel_type(u_up_w2, u_up, & - rmultiplicity_w2) ) - - ! Apply correction - if (geometry == geometry_spherical .and. topology == topology_fully_periodic) then - displacement => get_w3_to_w2_displacement(mesh%get_id()) - ! Correct horizontal winds - ! Vertical wind not needed for horizontal W2 DoFs, so don't correct - call invoke( w3_to_w2_correction_kernel_type(u_lon_w2, u_lon, 1, & - displacement, & - panel_id, 1), & - w3_to_w2_correction_kernel_type(u_lat_w2, u_lat, 1, & - displacement, & - panel_id, 1) ) - end if - - ! Convert from physical wind components into computational wind - call invoke( convert_phys_to_hdiv_kernel_type(u, u_lon_w2, u_lat_w2, & - u_up_w2, chi, panel_id, & - geometry) ) - - else if (sample_physics_winds) then + if (sample_physics_winds) then w2b_fs => function_space_collection%get_fs(mesh, 0, 0, W2broken) rmultiplicity_w2 => get_rmultiplicity_fv(W2, mesh%get_id()) @@ -308,6 +274,44 @@ contains dg_inc_matrix_vector_kernel_type(u_broken, u_up, u_up_map), & average_w2b_to_w2_kernel_type(u, u_broken, rmultiplicity_w2) ) + if (sample_physics_winds_correction & + .and. geometry == geometry_spherical & + .and. topology == topology_fully_periodic) then + + w2_fs => u%get_function_space() + call u_lon_w2%initialise( w2_fs ) + call u_lat_w2%initialise( w2_fs ) + call u_up_w2%initialise( w2_fs ) + call u_correction%initialise( w2_fs ) + call u_lon_large%initialise( u_lon%get_function_space(), halo_depth=2 ) + call u_lat_large%initialise( u_lat%get_function_space(), halo_depth=2 ) + + displacement => get_w3_to_w2_displacement(mesh%get_id()) + chi => get_coordinates(mesh%get_id()) + panel_id => get_panel_id(mesh%get_id()) + + call invoke( setval_c(u_lon_w2, 0.0_r_def), & + setval_c(u_lat_w2, 0.0_r_def), & + setval_c(u_up_w2, 0.0_r_def), & + ! Copy u_lon and u_lat to fields with appropriate depth + setval_X(u_lon_large, u_lon), & + setval_X(u_lat_large, u_lat), & + ! Correct horizontal wind components (but not vertical) + w3_to_w2_correction_kernel_type(u_lon_w2, u_lon_large, 1, & + displacement, & + panel_id, 1), & + w3_to_w2_correction_kernel_type(u_lat_w2, u_lat_large, 1, & + displacement, & + panel_id, 1), & + ! Convert components to HDiv field + convert_phys_to_hdiv_kernel_type(u_correction, & + u_lon_w2, u_lat_w2, & + u_up_w2, chi, panel_id, & + geometry), & + ! Increment wind with correction field + inc_X_plus_Y(u, u_correction) ) + end if + else call u%copy_field_properties(r_u) @@ -326,7 +330,7 @@ contains call mass_matrix_solver_alg(u, r_u) end if - if ( subroutine_timers ) call timer("set_wind") + if ( LPROF ) call stop_timing( id, 'mappings.set_wind' ) end subroutine set_wind diff --git a/science/gungho/source/algorithm/physics/map_physics_fields_alg_mod.x90 b/science/gungho/source/algorithm/physics/map_physics_fields_alg_mod.x90 index af4f90412..c5a046b47 100644 --- a/science/gungho/source/algorithm/physics/map_physics_fields_alg_mod.x90 +++ b/science/gungho/source/algorithm/physics/map_physics_fields_alg_mod.x90 @@ -34,9 +34,7 @@ module map_physics_fields_alg_mod use print_field_stats_alg_mod, only: print_field_stats_alg use sci_field_minmax_alg_mod, only: log_field_minmax - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer - + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none private @@ -88,10 +86,10 @@ contains type( mesh_type ), pointer :: mesh => null() - real(kind=r_def) :: l2 - - if ( subroutine_timers ) call timer("map_physics_fields") + real(kind=r_def) :: l2 + integer(tik) :: id + if ( LPROF ) call start_timing( id, 'mappings.map_physics_fields' ) mesh => u%get_mesh() call derived_fields%get_field('theta_in_w3', theta_in_w3) @@ -176,8 +174,7 @@ contains setval_X(u_in_w3_star, u_in_w3), & setval_X(v_in_w3_star, v_in_w3) ) end if - - if ( subroutine_timers ) call timer("map_physics_fields") + if ( LPROF ) call stop_timing( id, 'mappings.map_physics_fields' ) end subroutine map_physics_fields_alg diff --git a/science/gungho/source/algorithm/physics/slow_physics_alg_mod.X90 b/science/gungho/source/algorithm/physics/slow_physics_alg_mod.X90 index f2bbe547f..f6523d797 100644 --- a/science/gungho/source/algorithm/physics/slow_physics_alg_mod.X90 +++ b/science/gungho/source/algorithm/physics/slow_physics_alg_mod.X90 @@ -89,9 +89,8 @@ module slow_physics_alg_mod use formulation_config_mod, only: moisture_formulation, & moisture_formulation_dry, & theta_moist_source - use io_config_mod, only: subroutine_timers, & - write_conservation_diag - use timer_mod, only: timer + use io_config_mod, only: write_conservation_diag + use timing_mod, only: start_timing, stop_timing, tik, LPROF use external_forcing_alg_mod, only: external_forcing_alg use evap_condense_kernel_mod, only: evap_condense_kernel_type use physics_mappings_alg_mod, only: map_physics_scalars @@ -274,7 +273,7 @@ contains type( field_type ) :: conv_liquid_fraction, conv_frozen_fraction type( field_type ) :: conv_liquid_mmr, conv_frozen_mmr, conv_frozen_number ! ...for JULES & Boundary Layer - type( field_type ) :: recip_l_mo_sea, rhostar, h_blend_orog + type( field_type ) :: recip_l_mo_sea, rhostar type( field_type ) :: t1_sd_2d, q1_sd_2d ! ...for spectral GWD type( field_type ) :: du_spectral_gwd, dv_spectral_gwd @@ -364,8 +363,8 @@ contains type(mesh_type), pointer :: aerosol_mesh => null() type(mesh_type), pointer :: aerosol_twod_mesh => null() #endif - - if ( subroutine_timers ) call timer("slow_physics") + integer(tik) :: id + if ( LPROF ) call start_timing( id, 'slow_physics' ) !-------------------------------------------------------------------- ! Initialisation of fields and flags @@ -848,14 +847,14 @@ contains turbulence_fields, convection_fields, cloud_fields, & surface_fields, soil_fields, snow_fields, & aerosol_fields, recip_l_mo_sea, rhostar, & - h_blend_orog, t1_sd_2d, q1_sd_2d) + t1_sd_2d, q1_sd_2d) call bl_exp_alg(theta, rho, exner, mr_n, & derived_fields, radiation_fields, & microphysics_fields, dmr_mphys, orography_fields, & turbulence_fields, convection_fields, cloud_fields, & surface_fields, & recip_l_mo_sea, rhostar, & - h_blend_orog, t1_sd_2d, q1_sd_2d, clock) + t1_sd_2d, q1_sd_2d, clock) end if !-------------------------------------------------------------------- @@ -1175,8 +1174,7 @@ contains if (write_conservation_diag) & call moisture_conservation_alg( rho, mr, 'After slow' ) end if - - if ( subroutine_timers ) call timer("slow_physics") + if ( LPROF ) call stop_timing( id, 'slow_physics' ) end subroutine slow_physics diff --git a/science/gungho/source/algorithm/runtime_constants/dycore_constants_mod.x90 b/science/gungho/source/algorithm/runtime_constants/dycore_constants_mod.x90 index 9421aba5b..3baecd806 100644 --- a/science/gungho/source/algorithm/runtime_constants/dycore_constants_mod.x90 +++ b/science/gungho/source/algorithm/runtime_constants/dycore_constants_mod.x90 @@ -25,14 +25,15 @@ module dycore_constants_mod use function_space_collection_mod, only: function_space_collection use function_space_mod, only: function_space_type use inventory_by_mesh_mod, only: inventory_by_mesh_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_collection_mod, only: mesh_collection use mesh_mod, only: mesh_type use model_clock_mod, only: model_clock_type use operator_mod, only: operator_type use quadrature_xyoz_mod, only: quadrature_xyoz_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF + ! Configuration use finite_element_config_mod, only: element_order_h, & @@ -102,6 +103,7 @@ contains type(field_type), pointer :: panel_id type(quadrature_xyoz_type), pointer :: qr type(function_space_type), pointer :: w2_fs + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. coriolis_inventory%is_initialised()) then @@ -119,7 +121,7 @@ contains panel_id => get_panel_id(mesh_id) qr => get_qr_fe() - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call start_timing( id, 'runtime_constants.dycore' ) call coriolis_inventory%add_operator(coriolis, w2_fs, w2_fs, mesh) @@ -127,7 +129,7 @@ contains chi, panel_id, & scaled_omega, & f_lat, qr) ) - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call stop_timing( id, 'runtime_constants.dycore' ) end if ! Return constant @@ -156,6 +158,7 @@ contains type(quadrature_xyoz_type), pointer :: qr type(function_space_type), pointer :: w2_fs type(function_space_type), pointer :: wt_fs + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. vert_coriolis_inventory%is_initialised()) then @@ -174,7 +177,7 @@ contains panel_id => get_panel_id(mesh_id) qr => get_qr_fe() - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call start_timing( id, 'runtime_constants.dycore' ) call vert_coriolis_inventory%add_operator(vert_coriolis, wt_fs, w2_fs, mesh) @@ -182,7 +185,7 @@ contains chi, panel_id, & scaled_omega, & f_lat, qr) ) - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call stop_timing( id, 'runtime_constants.dycore' ) end if ! Return constant @@ -209,6 +212,7 @@ contains type(field_type), pointer :: geopotential type(field_type), pointer :: chi(:) type(function_space_type), pointer :: w3_fs + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. geopotential_inventory%is_initialised()) then @@ -224,7 +228,7 @@ contains element_order_v, W3) chi => get_coordinates(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call start_timing( id, 'runtime_constants.dycore' ) call geopotential_inventory%add_field(geopotential, w3_fs, mesh) @@ -240,7 +244,7 @@ contains call log_event( "Geopotential computation needs modifying "// & "for standard W3 mapping", LOG_LEVEL_ERROR ) end if - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call stop_timing( id, 'runtime_constants.dycore' ) end if ! Return constant @@ -293,6 +297,7 @@ contains real(kind=r_def) :: const real(kind=r_second) :: dt type(operator_type), pointer :: coriolis + integer(tik) :: id ! Check inventories are initialised if (.not. mm_w2_si_inventory%is_initialised()) then @@ -371,7 +376,7 @@ contains panel_id => get_panel_id(mesh_id) qr => get_qr_fe() - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call start_timing( id, 'runtime_constants.dycore' ) call invoke( name = "compute_damping_layer_mass_matrix", & compute_dl_matrix_kernel_type(mm_w2_dl, chi, panel_id, & dl_base, dl_str, & @@ -381,7 +386,7 @@ contains element_order_v, & dt_stored, & qr) ) - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call stop_timing( id, 'runtime_constants.dycore' ) else ! No damping layer, just copy the W2 mass matrix on this level mm_w2 => get_mass_matrix_fe(W2, mesh_id) @@ -399,7 +404,7 @@ contains call mm_w2_dl_lagged_inventory%get_operator(mesh, mm_w2_dl_lagged) else ! We are going to need to create this matrix - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call start_timing( id, 'runtime_constants.dycore' ) if (w2_op_name == w2_lagged_damping_layer_matrix) then ! This is our target matrix, so store it @@ -423,7 +428,7 @@ contains ! No lagged orography, just copy the W2 mass matrix on this level call invoke( operator_setval_x_kernel_type(mm_w2_dl_lagged, mm_w2_dl) ) end if - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call stop_timing( id, 'runtime_constants.dycore' ) end if end if @@ -431,7 +436,7 @@ contains ! S.I. MATRIX ! ====================================================================== ! if (w2_op_name == w2_si_matrix) then - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call start_timing( id, 'runtime_constants.dycore' ) call mm_w2_si_inventory%add_operator(mm_w2_si, fs, fs, mesh) if ( rotating ) then @@ -449,8 +454,7 @@ contains call invoke( name = "set_w2_si_mass_matrix_with_damping_layer", & operator_x_plus_ay_kernel_type(mm_w2_si, mm_w2_dl_lagged, & const, coriolis) ) - - if ( subroutine_timers ) call timer('runtime_constants.dycore') + if ( LPROF ) call stop_timing( id, 'runtime_constants.dycore' ) end if end if diff --git a/science/gungho/source/algorithm/runtime_constants/limited_area_constants_mod.x90 b/science/gungho/source/algorithm/runtime_constants/limited_area_constants_mod.x90 index c709f92a2..b1c8479ac 100644 --- a/science/gungho/source/algorithm/runtime_constants/limited_area_constants_mod.x90 +++ b/science/gungho/source/algorithm/runtime_constants/limited_area_constants_mod.x90 @@ -29,7 +29,6 @@ module limited_area_constants_mod use sci_geometric_constants_mod, only: get_coordinates use inventory_by_local_mesh_mod, only: inventory_by_local_mesh_type use inventory_by_mesh_mod, only: inventory_by_mesh_type - use io_config_mod, only: subroutine_timers use lfric_xios_write_mod, only: write_field_generic use local_mesh_mod, only: local_mesh_type use log_mod, only: log_event, & @@ -37,7 +36,8 @@ module limited_area_constants_mod LOG_LEVEL_DEBUG use mesh_collection_mod, only: mesh_collection use mesh_mod, only: mesh_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Configuration use base_mesh_config_mod, only: geometry, geometry_spherical @@ -165,9 +165,10 @@ contains type(field_type) :: w2parallel_mask type(field_type) :: w2perp_mask type(field_type) :: w2interior_mask + integer(tik) :: id ! Temporary mask fields to point to those in inventories - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) ! Point to the correct inventories if (use_fe) then @@ -259,7 +260,7 @@ contains if (run_log_level == run_log_level_debug) call list_mask_fields() - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end subroutine create_standard_masks @@ -296,8 +297,9 @@ contains integer(kind=i_def) :: i integer(kind=i_def) :: current_fs_id integer(kind=i_def) :: k_h, k_v + integer(tik) :: id - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) ! Point to the correct inventories if (use_fe) then @@ -356,7 +358,7 @@ contains ! Return function space chain to its position call multigrid_function_space_chain%set_current(current_fs_id) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end subroutine !> @brief Write out the name of each mask in the mask field collection @@ -659,6 +661,7 @@ contains type(inventory_by_mesh_type), pointer :: inventory character(len=str_def) :: inventory_name type(function_space_type), pointer :: fs + integer(tik) :: id ! Get appropriate inventory select case (space) @@ -690,14 +693,14 @@ contains ! Create constant if it doesn't already exist mask_r_def => get_mask_fe(space, mesh_id, finest_mesh_name) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, space) call inventory%add_field(mask_r_solver, fs, mesh) call copy_field(mask_r_def, mask_r_solver) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end if ! Return constant @@ -724,6 +727,7 @@ contains logical(kind=l_def) :: constant_exists type(inventory_by_mesh_type), pointer :: inventory character(len=str_def) :: inventory_name + integer(tik) :: id ! If running at lowest order, use finite volume if (element_order_h == 0 .and. element_order_v == 0) then @@ -753,7 +757,7 @@ contains if (.not. constant_exists) then ! Create constant if it doesn't already exist - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) ! Check if this is the finest mesh finest_mesh => mesh_collection%get_mesh(finest_mesh_name) @@ -767,7 +771,7 @@ contains call create_standard_masks(mesh, use_fe=.true., & finest_mesh_name=finest_mesh_name) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end if ! Return constant @@ -794,6 +798,7 @@ contains logical(kind=l_def) :: constant_exists type(inventory_by_mesh_type), pointer :: inventory character(len=str_def) :: inventory_name + integer(tik) :: id ! Get appropriate inventory select case (space) @@ -817,7 +822,7 @@ contains if (.not. constant_exists) then ! Create constant if it doesn't already exist - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) ! Check if this is the finest mesh finest_mesh => mesh_collection%get_mesh(finest_mesh_name) @@ -831,7 +836,7 @@ contains call create_standard_masks(mesh, use_fe=.false., & finest_mesh_name=finest_mesh_name) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end if ! Return constant @@ -861,6 +866,7 @@ contains character(len=str_def) :: inventory_name character(len=str_def) :: field_name type(function_space_type), pointer :: fs + integer(tik) :: id ! If running at lowest order, use finite volume if (element_order_h == 0 .and. element_order_v == 0) then @@ -902,7 +908,7 @@ contains onion_layers => get_onion_layers(mesh_id, finest_mesh_name) chi => get_coordinates(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, space) @@ -916,7 +922,7 @@ contains end if call mask_collection%add_field( mask_ptr ) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end if ! Return constant @@ -946,6 +952,7 @@ contains character(len=str_def) :: inventory_name character(len=str_def) :: field_name type(function_space_type), pointer :: fs + integer(tik) :: id ! Get appropriate inventory select case (space) @@ -981,7 +988,7 @@ contains onion_layers => get_onion_layers(mesh_id, finest_mesh_name) chi => get_coordinates(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) fs => function_space_collection%get_fs(mesh, 0, 0, space) call inventory%add_field(mask_ptr, fs, mesh, name=field_name) @@ -994,7 +1001,7 @@ contains end if call mask_collection%add_field( mask_ptr ) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end if ! Return constant @@ -1021,6 +1028,7 @@ contains type(field_type), pointer :: onion_layers logical(kind=l_def) :: constant_exists type(function_space_type), pointer :: w3_fs + integer(tik) :: id ! Initialise inventory if this is the first time getting this constant if (.not. onion_layers_inventory%is_initialised()) then @@ -1041,7 +1049,7 @@ contains if (prime_mesh%get_id() == finest_mesh%get_id()) then - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) ! Onion layers are only defined for lowest order finite elements w3_fs => function_space_collection%get_fs( & @@ -1062,7 +1070,7 @@ contains call mask_collection%initialise(name='mask_collection') end if call mask_collection%add_field( onion_layers ) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) else call log_event('Onion layers only implemented on finest mesh', LOG_LEVEL_ERROR) @@ -1095,6 +1103,7 @@ contains type(inventory_by_mesh_type), pointer :: inventory character(len=str_def) :: inventory_name type(function_space_type), pointer :: fs + integer(tik) :: id ! Get appropriate inventory select case (space) @@ -1127,7 +1136,7 @@ contains onion_layers => get_onion_layers(mesh_id, finest_mesh_name) chi => get_coordinates(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call start_timing( id, 'runtime_constants.limited_area' ) fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, space) @@ -1141,7 +1150,7 @@ contains end if call mask_collection%add_field( mask_ptr ) - if ( subroutine_timers ) call timer('runtime_constants.limited_area') + if ( LPROF ) call stop_timing( id, 'runtime_constants.limited_area' ) end if ! Return constant diff --git a/science/gungho/source/algorithm/runtime_constants/physics_constants_mod.X90 b/science/gungho/source/algorithm/runtime_constants/physics_constants_mod.X90 index db3321e1d..94a95dcf1 100644 --- a/science/gungho/source/algorithm/runtime_constants/physics_constants_mod.X90 +++ b/science/gungho/source/algorithm/runtime_constants/physics_constants_mod.X90 @@ -26,13 +26,13 @@ module physics_constants_mod use function_space_mod, only: function_space_type use inventory_by_mesh_mod, only: inventory_by_mesh_type use inventory_by_local_mesh_mod, only: inventory_by_local_mesh_type - use io_config_mod, only: subroutine_timers use local_mesh_mod, only: local_mesh_type use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_collection_mod, only: mesh_collection use mesh_mod, only: mesh_type use model_clock_mod, only: model_clock_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -120,6 +120,7 @@ contains integer(i_def), parameter :: n_centres = 1_i_def logical(l_def), parameter :: inc_surf = .true. logical(l_def), parameter :: ign_surf = .false. + integer(tik) :: id mesh_id = mesh%get_id() @@ -129,7 +130,7 @@ contains height_wth => get_height_fv(Wtheta, mesh_id) delta_at_wtheta => get_delta_at_wtheta(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.physics') + if ( LPROF ) call start_timing( id, 'runtime_constants.physics' ) if (.not. dtrdz_fd2_inventory%is_initialised()) then call dtrdz_fd2_inventory%initialise(name='dtrdz_fd2') @@ -207,7 +208,7 @@ contains inc_X_powint_n(max_diff_wtheta, 2_i_def), & inc_a_times_X(diffusion_const, max_diff_wtheta) ) - if ( subroutine_timers ) call timer('runtime_constants.physics') + if ( LPROF ) call stop_timing( id, 'runtime_constants.physics' ) end subroutine create_mixing_geometries @@ -408,6 +409,7 @@ contains type(mesh_type), pointer :: twod_mesh type(function_space_type), pointer :: fs logical(kind=l_def) :: constant_exists + integer(tik) :: id ! Check inventory is initialised if (.not. Pnm_star_inventory%is_initialised()) then @@ -425,14 +427,14 @@ contains latitude => get_latitude_fv(W3, mesh_id) fs => function_space_collection%get_fs(twod_mesh, 0, 0, W3, stph_spectral_dim) - if ( subroutine_timers ) call timer('runtime_constants.physics') + if ( LPROF ) call start_timing( id, 'runtime_constants.physics' ) call Pnm_star_inventory%add_field(Pnm_star, fs, local_mesh) call invoke( setval_c(Pnm_star, 0.0_r_def), & get_Pnm_star_kernel_type(Pnm_star, latitude, stph_n_max) ) - if ( subroutine_timers ) call timer('runtime_constants.physics') + if ( LPROF ) call stop_timing( id, 'runtime_constants.physics' ) end if call Pnm_star_inventory%get_field(local_mesh, Pnm_star) diff --git a/science/gungho/source/algorithm/runtime_constants/runtime_constants_mod.f90 b/science/gungho/source/algorithm/runtime_constants/runtime_constants_mod.f90 index b47d85b51..f304a3a0a 100644 --- a/science/gungho/source/algorithm/runtime_constants/runtime_constants_mod.f90 +++ b/science/gungho/source/algorithm/runtime_constants/runtime_constants_mod.f90 @@ -14,15 +14,12 @@ module runtime_constants_mod use base_mesh_config_mod, only: prime_mesh_name use constants_mod, only: i_def, l_def use formulation_config_mod, only: l_multigrid - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_INFO, & LOG_LEVEL_ERROR use mesh_collection_mod, only: mesh_collection use mesh_mod, only: mesh_type use model_clock_mod, only: model_clock_type use multigrid_config_mod, only: chain_mesh_tags - use timer_mod, only: timer - implicit none private @@ -47,8 +44,6 @@ subroutine create_runtime_constants() integer(kind=i_def), allocatable :: mg_mesh_ids(:) integer(kind=i_def) :: num_mg_meshes - if ( subroutine_timers ) call timer('runtime_constants_alg') - !==========================================================================! ! Turn all the meshes and coordinate fields into lists !==========================================================================! @@ -81,8 +76,6 @@ subroutine create_runtime_constants() ! code structure call runge_kutta_init() - if ( subroutine_timers ) call timer('runtime_constants_alg') - end subroutine create_runtime_constants diff --git a/science/gungho/source/algorithm/runtime_constants/solver_constants_mod.x90 b/science/gungho/source/algorithm/runtime_constants/solver_constants_mod.x90 index 2070e1038..eb1c31144 100644 --- a/science/gungho/source/algorithm/runtime_constants/solver_constants_mod.x90 +++ b/science/gungho/source/algorithm/runtime_constants/solver_constants_mod.x90 @@ -24,7 +24,6 @@ module solver_constants_mod use function_space_collection_mod, only: function_space_collection use function_space_mod, only: function_space_type use inventory_by_mesh_mod, only: inventory_by_mesh_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_collection_mod, only: mesh_collection use mesh_mod, only: mesh_type @@ -32,7 +31,8 @@ module solver_constants_mod r_solver_operator_type use quadrature_xyoz_mod, only: quadrature_xyoz_type use r_solver_field_mod, only: r_solver_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Configuration use finite_element_config_mod, only: element_order_h, & @@ -107,6 +107,7 @@ contains type(field_type), pointer :: chi(:) type(field_type), pointer :: panel_id type(function_space_type), pointer :: w3_fs + integer(tik) :: id ! Check inventory is initialised if (.not. detj_at_w3_r_solver_inventory%is_initialised()) then @@ -122,7 +123,7 @@ contains panel_id => get_panel_id(mesh_id) ! Create the object as it doesn't exist yet - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call start_timing( id, 'runtime_constants.solver' ) w3_fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, W3) @@ -131,7 +132,7 @@ contains halo_depth = 0 ! No need to calculate into halos call invoke( calc_detj_at_w3_kernel_type(detj_r_solver, chi, panel_id, & halo_depth) ) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call stop_timing( id, 'runtime_constants.solver' ) end if ! Get existing constant @@ -162,6 +163,7 @@ contains type(r_solver_operator_type), pointer :: mm_r_solver type(inventory_by_mesh_type), pointer :: inventory character(len=str_def) :: inventory_name + integer(tik) :: id ! Point to appropriate inventory for this space select case (space) @@ -189,7 +191,7 @@ contains ! Create constant if it doesn't already exist mm_r_def => get_mass_matrix_fe(space, mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call start_timing( id, 'runtime_constants.solver' ) fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, space) @@ -197,7 +199,7 @@ contains call invoke( operator_setval_x_kernel_type(mm_r_solver, mm_r_def) ) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call stop_timing( id, 'runtime_constants.solver' ) end if ! Return existing constant @@ -223,6 +225,7 @@ contains type(r_solver_operator_type), pointer :: mm_inv_r_solver type(inventory_by_mesh_type), pointer :: inventory character(len=str_def) :: inventory_name + integer(tik) :: id ! Point to appropriate inventory for this space select case (space) @@ -247,7 +250,7 @@ contains ! Create constant if it doesn't already exist mm_inv_r_def => get_inverse_mass_matrix_fe(space, mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call start_timing( id, 'runtime_constants.solver' ) fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, space) @@ -255,7 +258,7 @@ contains call invoke( operator_setval_x_kernel_type(mm_inv_r_solver, mm_inv_r_def) ) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call stop_timing( id, 'runtime_constants.solver' ) end if ! Return existing constant @@ -284,6 +287,7 @@ contains type(operator_type), pointer :: mm_r_def type(r_solver_operator_type), pointer :: mm_r_solver type(inventory_by_mesh_type), pointer :: inventory + integer(tik) :: id ! Determine which inventory to point to select case (w2_op_name) @@ -307,7 +311,7 @@ contains ! Create constant if it doesn't already exist mm_r_def => get_w2_mass_matrix(w2_op_name, mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call start_timing( id, 'runtime_constants.solver' ) fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, W2) @@ -315,7 +319,7 @@ contains call invoke( operator_setval_x_kernel_type(mm_r_solver, mm_r_def) ) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call stop_timing( id, 'runtime_constants.solver' ) end if ! Return existing constant @@ -344,6 +348,7 @@ contains type(quadrature_xyoz_type), pointer :: qr type(function_space_type), pointer :: w3_fs type(function_space_type), pointer :: w2_fs + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. im3_div_r_solver_inventory%is_initialised()) then @@ -366,7 +371,7 @@ contains w3_fs => function_space_collection%get_fs( mesh, element_order_h, & element_order_v, W3 ) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call start_timing( id, 'runtime_constants.solver' ) call div_r_solver%initialise( w3_fs, w2_fs ) call im3_div_r_solver_inventory%add_operator(im3_div_r_solver, w3_fs, w2_fs, mesh) ! @TODO #416: may be able to optimise memory by calculating div @@ -375,7 +380,7 @@ contains operator_x_times_y_kernel_type(im3_div_r_solver, & mm_w3_inv_r_solver, & div_r_solver) ) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call stop_timing( id, 'runtime_constants.solver' ) end if call im3_div_r_solver_inventory%get_operator(mesh, im3_div_r_solver) @@ -408,6 +413,7 @@ contains type(field_type), pointer :: panel_id type(function_space_type), pointer :: fs integer(kind=i_def), parameter :: i_minus_one = -1_i_def + integer(tik) :: id ! Special case, Wtheta normalisation is the lumped inverse mass matrix select case (space) @@ -430,7 +436,7 @@ contains fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, space) - if ( subroutine_timers ) call timer('runtime_constants.fem') + if ( LPROF ) call start_timing( id, 'runtime_constants.fem' ) call nodal_multiplicity%initialise( fs ) call w2_normalisation_inventory%add_field(normalisation, fs, mesh) @@ -443,7 +449,7 @@ contains nodal_multiplicity), & inc_X_powint_n(normalisation, i_minus_one) ) - if ( subroutine_timers ) call timer('runtime_constants.fem') + if ( LPROF ) call stop_timing( id, 'runtime_constants.fem' ) end if ! Return constant @@ -473,6 +479,7 @@ contains type(r_solver_field_type), pointer :: normalisation_r_solver type(inventory_by_mesh_type), pointer :: inventory character(len=str_def) :: inventory_name + integer(tik) :: id ! Point to appropriate inventory for this space select case (space) @@ -500,7 +507,7 @@ contains ! Create constant if it doesn't already exist normalisation_r_def => get_normalisation(space, mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call start_timing( id, 'runtime_constants.solver' ) fs => function_space_collection%get_fs(mesh, element_order_h, & element_order_v, space) @@ -508,7 +515,7 @@ contains call copy_field(normalisation_r_def, normalisation_r_solver) - if ( subroutine_timers ) call timer('runtime_constants.solver') + if ( LPROF ) call stop_timing( id, 'runtime_constants.solver' ) end if ! Return existing constant diff --git a/science/gungho/source/algorithm/runtime_constants/transport_constants_mod.x90 b/science/gungho/source/algorithm/runtime_constants/transport_constants_mod.x90 index 4da0c7222..9fc70bf38 100644 --- a/science/gungho/source/algorithm/runtime_constants/transport_constants_mod.x90 +++ b/science/gungho/source/algorithm/runtime_constants/transport_constants_mod.x90 @@ -31,7 +31,6 @@ module transport_constants_mod use integer_field_mod, only: integer_field_type use inventory_by_mesh_mod, only: inventory_by_mesh_type use inventory_by_local_mesh_mod, only: inventory_by_local_mesh_type - use io_config_mod, only: subroutine_timers use local_mesh_mod, only: local_mesh_type use log_mod, only: log_event, log_scratch_space, & LOG_LEVEL_ERROR, & @@ -48,7 +47,8 @@ module transport_constants_mod use reference_element_mod, only: reference_element_type use r_tran_field_mod, only: r_tran_field_type use sci_field_minmax_alg_mod, only: get_field_minmax - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Kernels use sci_operator_algebra_kernel_mod, only: operator_setval_x_kernel_type @@ -183,8 +183,9 @@ contains logical(kind=l_def) :: linear_remap integer(kind=i_def) :: ndata, halo_depth + integer(tik) :: id - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) if (.not. ext_mesh_weights_inventory%is_initialised()) then call ext_mesh_weights_inventory%initialise(name="extended_mesh_weights") @@ -227,7 +228,7 @@ contains linear_remap, ndata & ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end subroutine initialise_remap_on_extended_mesh @@ -257,8 +258,9 @@ contains type(field_type), pointer :: panel_id integer(kind=i_def) :: ncolumns_1d integer(kind=i_def), parameter :: MINUS_FAR_AWAY = -FAR_AWAY + integer(tik) :: id - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) ! Initialise inventories if they haven't already been if (.not. panel_edge_dist_inventory%is_initialised()) then @@ -306,7 +308,7 @@ contains int_setval_c(panel_edge_dist(4), MINUS_FAR_AWAY) ) end if - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end subroutine compute_panel_edge_dists @@ -333,10 +335,11 @@ contains type(field_type), pointer :: panel_edge_coords_y(:) type(field_type), pointer :: chi(:) type(field_type), pointer :: panel_id + integer(kind=tik) :: id panel_edge_dist => get_panel_edge_dist(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) ! Initialise inventories if they haven't already been if (.not. panel_edge_coords_x_inventory%is_initialised()) then @@ -368,7 +371,7 @@ contains panel_edge_dist, & depth, field_depth) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end subroutine compute_panel_edge_coords @@ -400,6 +403,7 @@ contains type(function_space_type), pointer :: w3_fs integer(kind=i_def) :: ndata, max_halo_depth, remap_depth, cross_depth + integer(kind=tik) :: id ! Get pointers to coordinates and masks for panel edges chi => get_coordinates(mesh_id) @@ -408,7 +412,7 @@ contains panel_edge_coords_x => get_panel_edge_coords_x(mesh_id) panel_edge_coords_y => get_panel_edge_coords_y(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) ! Set up fields on 2D mesh in multidata W3 space mesh => mesh_collection%get_mesh(mesh_id) @@ -479,7 +483,7 @@ contains remap_depth) & ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end subroutine compute_panel_edge_weights @@ -503,8 +507,9 @@ contains type(function_space_type), pointer :: w3_fs integer(kind=i_def) :: max_halo_depth, cross_depth + integer(kind=tik) :: id - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) ! Set up fields on 2D mesh in multidata W3 space mesh => mesh_collection%get_mesh(mesh_id) @@ -539,7 +544,7 @@ contains call invoke_halo_mask_xy_kernel_type(halo_mask_x, halo_mask_y, halo_mask, & cross_depth, max_halo_depth) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end subroutine compute_halo_masks @@ -559,6 +564,7 @@ contains type(r_tran_field_type) :: dz_w3_rtran type(field_type), pointer :: dz_w3_rdef type(function_space_type), pointer :: w3_fs + integer(tik) :: id ! Check inventory is initialised if (.not. third_dla_dz_inventory%is_initialised()) then @@ -573,7 +579,7 @@ contains mesh => mesh_collection%get_mesh(mesh_id) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) w3_fs => function_space_collection%get_fs(mesh, 0, 0, W3) @@ -586,7 +592,7 @@ contains call invoke( ffsl_third_dldz_kernel_type(dla_dz, dlb_dz, dz_w3_rtran) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end subroutine compute_third_dl_dz @@ -617,6 +623,7 @@ contains type(field_type), pointer :: panel_id type(field_type), pointer :: detj_r_def type(function_space_type), pointer :: w3_fs + integer(tik) :: id ! Check inventory is initialised if (.not. detj_at_w3_r_tran_inventory%is_initialised()) then @@ -646,7 +653,7 @@ contains panel_id => get_panel_id(mesh_id) ! Create the object as it doesn't exist yet - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) w3_fs => function_space_collection%get_fs(mesh, & element_order_h, & @@ -662,7 +669,7 @@ contains else call copy_field(detj_r_def, detj_r_tran) end if - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Get existing constant @@ -693,6 +700,7 @@ contains integer(kind=i_def) :: detj_direction integer(kind=i_def) :: element_order_h, & element_order_v + integer(tik) :: id ! Check inventory is initialised if (.not. detj_at_w2_above_inventory%is_initialised()) then @@ -718,7 +726,7 @@ contains end if ! Create the object as it doesn't exist yet - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) detj_direction = 1 w2_fs => function_space_collection%get_fs(mesh, & @@ -731,7 +739,7 @@ contains calc_directional_detj_at_w2_kernel_type(detj_above, & chi, panel_id, & detj_direction) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Get existing constant @@ -762,6 +770,7 @@ contains integer(kind=i_def) :: detj_direction integer(kind=i_def) :: element_order_h, & element_order_v + integer(tik) :: id ! Check inventory is initialised if (.not. detj_at_w2_below_inventory%is_initialised()) then @@ -786,7 +795,7 @@ contains end if ! Create the object as it doesn't exist yet - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) detj_direction = 0 w2_fs => function_space_collection%get_fs(mesh, & @@ -799,7 +808,7 @@ contains calc_directional_detj_at_w2_kernel_type(detj_below, & chi, panel_id, & detj_direction) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Get existing constant @@ -887,6 +896,7 @@ contains type(r_tran_field_type) :: dz_w3_rtran type(field_type), pointer :: dz_w3_rdef type(function_space_type), pointer :: w2v_fs + integer(tik) :: id ! Check inventory is initialised if (.not. fourth_dl_dz_inventory%is_initialised()) then @@ -900,7 +910,7 @@ contains if (.not. constant_exists) then ! Create the object as it doesn't exist yet - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) w2v_fs => function_space_collection%get_fs(mesh, 0, 0, W2v) @@ -912,7 +922,7 @@ contains call invoke( ffsl_fourth_dldz_kernel_type(dl_dz, dz_w3_rtran) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Get existing constant @@ -946,6 +956,7 @@ contains character(len=str_def) :: inventory_name integer(kind=i_def) :: element_order_h, & element_order_v + integer(tik) :: id ! Point to appropriate inventory for this space select case (space) @@ -978,7 +989,7 @@ contains mm_r_def => get_mass_matrix_fe(space, mesh_id) end if - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) fs => function_space_collection%get_fs(mesh, & element_order_h, & @@ -988,7 +999,7 @@ contains call invoke( operator_setval_x_kernel_type(mm_r_tran, mm_r_def) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Return existing constant @@ -1018,6 +1029,7 @@ contains character(len=str_def) :: inventory_name integer(kind=i_def) :: element_order_h, & element_order_v + integer(tik) :: id ! Point to appropriate inventory for this space select case (space) @@ -1050,7 +1062,7 @@ contains mm_inv_r_def => get_inverse_mass_matrix_fe(space, mesh_id) end if - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) fs => function_space_collection%get_fs(mesh, & element_order_h, & @@ -1060,7 +1072,7 @@ contains call invoke( operator_setval_x_kernel_type(mm_inv_r_tran, mm_inv_r_def) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Return existing constant @@ -1139,6 +1151,7 @@ contains integer(kind=i_def) :: fs_id integer(kind=i_def) :: element_order_h, & element_order_v + integer(tik) :: id ! Point to appropriate inventory for this space select case (direction) @@ -1195,14 +1208,14 @@ contains w3_fs => function_space_collection%get_fs( mesh, element_order_h, & element_order_v, W3 ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) call div%initialise( w3_fs, w2_fs ) call im3_div%initialise( w3_fs, w2_fs ) call inventory%add_operator(im3_div_r_tran, w3_fs, w2_fs, mesh) call invoke( compute_div_operator_kernel_type(div, chi, panel_id, qr), & operator_x_times_y_kernel_type(im3_div, mm_w3_inv, div), & operator_setval_x_kernel_type(im3_div_r_tran, im3_div) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if call inventory%get_operator(mesh, im3_div_r_tran) @@ -1634,6 +1647,7 @@ contains integer(kind=i_def) :: nqp_xy, nqp_z, nqp_xyz integer(kind=i_def) :: element_order_h, element_order_v real(kind=r_def) :: transform_radius, chi3_max + integer(tik) :: id class(reference_element_type), pointer :: reference_element @@ -1667,7 +1681,7 @@ contains chi => get_coordinates(mesh%get_id()) panel_id => get_panel_id(mesh%get_id()) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) reference_element => mesh%get_reference_element() @@ -1792,7 +1806,7 @@ contains qr, qrf) ) end if - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if @@ -1822,6 +1836,7 @@ contains logical(kind=l_def) :: constant_exists type(quadrature_rule_gaussian_type) :: gaussian_quadrature type(quadrature_xyoz_type) :: qr + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. vert_w3_mol_coeffs_inventory%is_initialised()) then @@ -1835,7 +1850,7 @@ contains if (.not. constant_exists) then height => get_height_fv(Wtheta, mesh%get_id()) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) ndata_v = 2*(fv_vertical_order + 1) nqp_xyz = fv_vertical_order + 1_i_def qr = quadrature_xyoz_type(nqp_xyz, gaussian_quadrature) @@ -1854,7 +1869,7 @@ contains ndata_v, & fv_vertical_order, & qr) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Return constant @@ -1884,6 +1899,7 @@ contains logical(kind=l_def) :: constant_exists type(quadrature_rule_gaussian_type) :: gaussian_quadrature type(quadrature_xyoz_type) :: qr + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. rev_vert_w3_mol_coeffs_inventory%is_initialised()) then @@ -1899,7 +1915,7 @@ contains if (.not. constant_exists) then height => get_height_fv(Wtheta, mesh%get_id()) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) vertical_order = fv_vertical_order - 1 ndata_v = fv_vertical_order nqp_xyz = fv_vertical_order + 1_i_def @@ -1918,7 +1934,7 @@ contains ndata_v, & vertical_order, & qr) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Return constant @@ -1980,6 +1996,7 @@ contains real(kind=r_def) :: transform_radius, chi3_max type(quadrature_rule_gauss_lobatto_type) :: gauss_lobatto_quadrature class(reference_element_type), pointer :: reference_element + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. hori_wt_mol_coeffs_inventory%is_initialised()) then @@ -2009,7 +2026,7 @@ contains chi => get_coordinates(mesh%get_id()) panel_id => get_panel_id(mesh%get_id()) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) reference_element => mesh%get_reference_element() @@ -2138,7 +2155,7 @@ contains qr, qre) ) end if - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if @@ -2166,6 +2183,7 @@ contains integer(kind=i_def) :: vertical_order integer(kind=i_def) :: ndata_v logical(kind=l_def) :: constant_exists + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. vert_wt_mol_coeffs_inventory%is_initialised()) then @@ -2179,7 +2197,7 @@ contains if (.not. constant_exists) then height => get_height_fv(Wtheta, mesh%get_id()) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) vertical_order = fv_vertical_order + 1 ndata_v = 2*(vertical_order + 1) ! Set up function space @@ -2195,7 +2213,7 @@ contains height, & ndata_v, & vertical_order) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Return constant @@ -2221,6 +2239,7 @@ contains type(function_space_type), pointer :: multidata_fs integer(kind=i_def) :: ndata_v logical(kind=l_def) :: constant_exists + integer(tik) :: id ! Initialise inventory if it hasn't been done so already if (.not. rev_vert_wt_mol_coeffs_inventory%is_initialised()) then @@ -2236,7 +2255,7 @@ contains if (.not. constant_exists) then height => get_height_fv(Wtheta, mesh%get_id()) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call start_timing( id, 'runtime_constants.transport' ) ndata_v = 2*(fv_vertical_order + 1) ! Set up function space multidata_fs => function_space_collection%get_fs( & @@ -2251,7 +2270,7 @@ contains height, & ndata_v, & fv_vertical_order) ) - if ( subroutine_timers ) call timer('runtime_constants.transport') + if ( LPROF ) call stop_timing( id, 'runtime_constants.transport' ) end if ! Return constant diff --git a/science/gungho/source/algorithm/solver/lam_rhs_alg_mod.x90 b/science/gungho/source/algorithm/solver/lam_rhs_alg_mod.x90 index 17342e738..352353c5c 100644 --- a/science/gungho/source/algorithm/solver/lam_rhs_alg_mod.x90 +++ b/science/gungho/source/algorithm/solver/lam_rhs_alg_mod.x90 @@ -15,7 +15,7 @@ module lam_rhs_alg_mod use dg_inc_matrix_vector_kernel_mod, & only: dg_inc_matrix_vector_kernel_type use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use derived_config_mod, only: bundle_size use si_operators_alg_mod, only: get_rho_at_u use sci_fem_constants_mod, only: get_im3_div_fe @@ -88,9 +88,8 @@ contains !> @param[in] model_clock Time in the model !> @param[in] finest_mesh_name Name of the finest mesh !> @param[in] tau_r Relaxation parameter for density in semi-implicit method - !> @param[in] subroutine_timers Enable output of subroutine runtimes subroutine calc_rhs_lbc( rhs, lbc_fields, model_clock, finest_mesh_name, & - tau_r, subroutine_timers ) + tau_r ) implicit none @@ -99,7 +98,6 @@ contains class(model_clock_type), intent(in) :: model_clock character(len=str_def), intent(in) :: finest_mesh_name real(r_def), intent(in) :: tau_r - logical(l_def), intent(in) :: subroutine_timers type(field_type), pointer :: boundary_u => null() type(operator_type), pointer :: mm_vel => null(), & @@ -119,9 +117,9 @@ contains integer(i_def) :: mesh_id type(r_solver_field_type), pointer :: r_solver_rho_at_u => null() + integer(tik) :: id - - if ( subroutine_timers ) call timer('rhs_lbc') + if ( LPROF ) call start_timing( id, 'dynamics.rhs_lbc' ) mesh_id = rhs(igh_u)%get_mesh_id() @@ -190,7 +188,7 @@ contains nullify ( div, mt_lumped_inv, m2_diag, mm_vel ) nullify ( r_solver_rho_at_u ) - if ( subroutine_timers ) call timer('rhs_lbc') + if ( LPROF ) call stop_timing( id, 'dynamics.rhs_lbc' ) end subroutine calc_rhs_lbc diff --git a/science/gungho/source/algorithm/solver/mixed_operator_alg_mod.x90 b/science/gungho/source/algorithm/solver/mixed_operator_alg_mod.x90 index 72454b170..63faab91c 100644 --- a/science/gungho/source/algorithm/solver/mixed_operator_alg_mod.x90 +++ b/science/gungho/source/algorithm/solver/mixed_operator_alg_mod.x90 @@ -96,9 +96,9 @@ contains subroutine apply_mixed_operator(self, x, y) use boundaries_config_mod, only: limited_area - use io_config_mod, only: subroutine_timers use timestepping_config_mod, only: dt, tau_r - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use field_indices_mod, only: isol_u, isol_p, & isol_w, isol_uv use operator_mod, only: r_solver_operator_type @@ -116,21 +116,17 @@ contains use limited_area_constants_mod, only: get_mask_r_solver use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use function_space_mod, only: function_space_type - use fs_continuity_mod, only: W2, W2h, W2v, W3, Wtheta + use fs_continuity_mod, only: W2, W2h, W2v, W3, Wtheta, W2Hbroken use function_space_collection_mod, only: function_space_collection - use apply_mixed_lu_operator_kernel_mod, & - only: apply_mixed_lu_operator_kernel_type - use apply_mixed_operator_kernel_mod, & - only: apply_mixed_operator_kernel_type + use apply_mixed_lu_operator_kernel_mod, only: apply_mixed_lu_operator_kernel_type use apply_elim_mixed_lp_operator_kernel_mod, & - only: apply_elim_mixed_lp_operator_kernel_type - use matrix_vector_kernel_mod, & - only: matrix_vector_kernel_type - use dg_inc_matrix_vector_kernel_mod, & - only: dg_inc_matrix_vector_kernel_type - use apply_mixed_operator_kernel_mod, & - only: apply_mixed_operator_kernel_type + only: apply_elim_mixed_lp_operator_kernel_type + use matrix_vector_kernel_mod, only: matrix_vector_kernel_type + use dg_inc_matrix_vector_kernel_mod, only: dg_inc_matrix_vector_kernel_type + use apply_mixed_u_operator_kernel_mod, only: apply_mixed_u_operator_kernel_type + use apply_mixed_wp_operator_kernel_mod, only: apply_mixed_wp_operator_kernel_type + use assemble_w2h_from_w2hb_kernel_mod, only: assemble_w2h_from_w2hb_kernel_type implicit none @@ -148,7 +144,8 @@ contains m2_diag type(r_solver_field_type) :: x_uvw, y_uvw type(function_space_type), pointer :: u_fs, & - t_fs + t_fs, & + w2hb_fs integer(i_def) :: p_h, p_v type(r_solver_field_type), pointer :: w2_mask, & w3_mask @@ -172,8 +169,11 @@ contains type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns + integer(tik) :: id - if ( subroutine_timers ) call timer('mixed_operator') + type(r_solver_field_type) :: y_uv_broken + + if ( LPROF ) call start_timing( id, 'mixed_solver.operator' ) ! Extract mesh ID select type (y) @@ -224,6 +224,8 @@ contains xvec_w => x%get_field_from_position(isol_w) yvec_w => y%get_field_from_position(isol_w) end if + p_h = y%vector(isol_u)%get_element_order_h() + p_v = y%vector(isol_u)%get_element_order_v() ! Check if we can use the optimised operator setup optimised_operator = ( p2theta_vert .and. & @@ -235,8 +237,6 @@ contains if ( .not. optimised_operator ) then ! Create fields in 3D W2 space - p_h = y%vector(isol_u)%get_element_order_h() - p_v = y%vector(isol_u)%get_element_order_v() u_fs => function_space_collection%get_fs( mesh, p_h, p_v, W2 ) call x_uvw%initialise( vector_space = u_fs ) @@ -256,13 +256,28 @@ contains case ( eliminate_variables_discrete ) q32_op => get_eliminated_q32() if ( optimised_operator ) then - call invoke( name="apply_mixed_operator_new", & - setval_c( yvec_uv, 0.0_r_solver ), & - apply_mixed_operator_kernel_type( yvec_uv, yvec_w, yvec_p, & - xvec_uv, xvec_w, xvec_p, & - ptheta2, mt_lumped_inv, & - mm_vel, p2theta, div_star, m2_diag, & - m3_exner_star, q32_op, p3theta ) ) + ! Compute the lhs of mixed operator in two steps: + ! 1) Compute the horizontal wind lhs (yvec_uv), this is done in the broken W2 + ! space to avoid having to halo exchange the input fields. After computation of + ! the broken W2 lhs the continuous W2 lhs is computed which only requires a single + ! halo exchange. + ! 2) Compute the vertical wind (yvec_w) & pressure (yvec_p) lhs, since these + ! are horizontally discontinuous fields then there are no further halo exchanges required. + + ! Create broken y_uv + w2hb_fs => function_space_collection%get_fs(mesh, p_h, p_v, W2Hbroken) + call y_uv_broken%initialise( w2hb_fs ) + call invoke( name="apply_split_mixed_operator", & + apply_mixed_u_operator_kernel_type( y_uv_broken, & + xvec_uv, xvec_w, xvec_p, & + mm_vel, div_star, m2_diag ), & + setval_c( yvec_uv, 0.0_r_solver ), & + assemble_w2h_from_w2hb_kernel_type(yvec_uv, y_uv_broken), & + apply_mixed_wp_operator_kernel_type( yvec_w, yvec_p, & + xvec_uv, xvec_w, xvec_p, & + ptheta2, mt_lumped_inv, & + mm_vel, p2theta, div_star, m2_diag, & + m3_exner_star, q32_op, p3theta ) ) else ! Create theta' field t_fs => function_space_collection%get_fs( mesh, p_h, p_v, Wtheta ) @@ -359,7 +374,7 @@ contains call log_event(log_scratch_space, LOG_LEVEL_ERROR) end select - if ( subroutine_timers ) call timer('mixed_operator') + if ( LPROF ) call stop_timing( id, 'mixed_solver.operator' ) end subroutine apply_mixed_operator diff --git a/science/gungho/source/algorithm/solver/mixed_schur_preconditioner_alg_mod.x90 b/science/gungho/source/algorithm/solver/mixed_schur_preconditioner_alg_mod.x90 index e9f613b8c..70072ae47 100644 --- a/science/gungho/source/algorithm/solver/mixed_schur_preconditioner_alg_mod.x90 +++ b/science/gungho/source/algorithm/solver/mixed_schur_preconditioner_alg_mod.x90 @@ -100,8 +100,8 @@ module mixed_schur_preconditioner_alg_mod use sci_r_solver_field_vector_mod, only: r_solver_field_vector_type use field_indices_mod, only: isol_u, isol_p, & isol_uv, isol_w - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use mixed_solver_config_mod, only: split_w use log_mod, only: log_event, & LOG_LEVEL_ERROR, & @@ -248,8 +248,10 @@ contains class(mixed_schur_preconditioner_type), intent(inout) :: self class(abstract_vector_type), intent(in) :: x class(abstract_vector_type), intent(inout) :: y + integer(tik) :: id_precon, & + id_solve - if ( subroutine_timers ) call timer('mixed_schur_preconditioner_alg') + if ( LPROF ) call start_timing( id_precon, 'mixed_solver.schur_precon' ) select type(x) type is(r_solver_field_vector_type) @@ -260,7 +262,7 @@ contains ! STEP 2: Solve Helmholtz system ! Krylov solver to obtain pressure increment - if ( subroutine_timers ) call timer('mixed_schur solve') + if ( LPROF ) call start_timing(id_solve, 'schur_precon.pressure_solver') ! Set initial guess to pressure incremenet to 0 call self%pressure_x%set_scalar(0.0_r_def) @@ -269,7 +271,7 @@ contains call log_event('Schur preconditioner pressure solve:', LOG_LEVEL_DEBUG) call self%pressure_solver%apply(self%pressure_x, self%pressure_b) - if ( subroutine_timers ) call timer('mixed_schur solve') + if ( LPROF ) call stop_timing(id_solve, 'schur_precon.pressure_solver') ! STEP 3: Back substitute to obtain other fields call self%back_substitute(y) @@ -285,7 +287,7 @@ contains call log_event(log_scratch_space, LOG_LEVEL_ERROR) end select - if ( subroutine_timers ) call timer('mixed_schur_preconditioner_alg') + if ( LPROF ) call stop_timing( id_precon, 'mixed_solver.schur_precon' ) end subroutine apply_mixed_schur_preconditioner @@ -336,8 +338,9 @@ contains type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns + integer(tik) :: id - if ( subroutine_timers ) call timer('mixed_schur rhs') + if ( LPROF ) call start_timing( id, 'schur_precon.rhs' ) rhs => self%pressure_b%get_field_from_position(1) @@ -414,7 +417,7 @@ contains call invoke( inc_X_times_Y(rhs, h_diag) ) end if - if ( subroutine_timers ) call timer('mixed_schur rhs') + if ( LPROF ) call stop_timing( id, 'schur_precon.rhs' ) end subroutine build_pressure_rhs @@ -452,8 +455,10 @@ contains exner_inc type(r_solver_field_type), target :: dummy_field + type(r_solver_field_type), target :: uvw_norm + integer(tik) :: id - if ( subroutine_timers ) call timer('Schur back substitute') + if ( LPROF ) call start_timing( id, 'schur_precon.back_sub' ) exner_inc => self%pressure_x%get_field_from_position(1) @@ -475,11 +480,13 @@ contains call dummy_field%initialise( vector_space = self%rhs_u%get_function_space() ) w2_mask => dummy_field end if + call uvw_norm%initialise( vector_space = self%rhs_u%get_function_space() ) call invoke( name = "compute_split_increments", & + X_times_Y(uvw_norm, u_normalisation, Hb_lumped_inv), & setval_c(state_uv, 0.0_r_solver), & schur_backsub_kernel_type( state_uv, state_w, self%rhs_u, & exner_inc, div_star, & - u_normalisation, Hb_lumped_inv, & + uvw_norm, & limited_area, w2_mask ) ) else call u_inc%initialise( vector_space = self%rhs_u%get_function_space() ) @@ -502,7 +509,7 @@ contains state_p => state%get_field_from_position(isol_p) call invoke( setval_X(state_p, exner_inc) ) - if ( subroutine_timers ) call timer('Schur back substitute') + if ( LPROF ) call stop_timing( id, 'schur_precon.back_sub' ) end subroutine back_substitute diff --git a/science/gungho/source/algorithm/solver/pressure_operator_alg_mod.x90 b/science/gungho/source/algorithm/solver/pressure_operator_alg_mod.x90 index cbc33df07..289c66802 100644 --- a/science/gungho/source/algorithm/solver/pressure_operator_alg_mod.x90 +++ b/science/gungho/source/algorithm/solver/pressure_operator_alg_mod.x90 @@ -132,8 +132,8 @@ contains use operator_mod, only: r_solver_operator_type use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type use apply_variable_hx_kernel_mod, only: apply_variable_hx_kernel_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use helmholtz_solver_config_mod, only: normalise use apply_helmholtz_operator_kernel_mod, & only: apply_helmholtz_operator_kernel_type @@ -165,8 +165,9 @@ contains integer(kind=i_def), parameter :: one_int = 1_i_def integer(kind=i_def) :: mesh_id logical(kind=l_def) :: lam_mesh + integer(tik) :: id - if ( subroutine_timers ) call timer('helmholtz lhs') + if ( LPROF ) call start_timing( id, 'pressure_solver.helmholtz_lhs' ) select type (x) type is (r_solver_field_vector_type) @@ -241,7 +242,6 @@ contains nullify( w3_mask, w2_mask ) end if nullify( x_vec, y_vec ) - if ( subroutine_timers ) call timer('helmholtz lhs') class default @@ -257,6 +257,7 @@ contains call log_event(log_scratch_space, LOG_LEVEL_ERROR) end select + if ( LPROF ) call stop_timing( id, 'pressure_solver.helmholtz_lhs' ) end subroutine apply_pressure_operator diff --git a/science/gungho/source/algorithm/solver/semi_implicit_solver_alg_mod.x90 b/science/gungho/source/algorithm/solver/semi_implicit_solver_alg_mod.x90 index 893deb5b1..ca02473b8 100644 --- a/science/gungho/source/algorithm/solver/semi_implicit_solver_alg_mod.x90 +++ b/science/gungho/source/algorithm/solver/semi_implicit_solver_alg_mod.x90 @@ -70,8 +70,8 @@ module semi_implicit_solver_alg_mod use combine_w2_field_kernel_mod, only: combine_w2_field_kernel_type ! IO - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -573,8 +573,9 @@ contains integer( kind=i_def ) :: mesh_id type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns + integer(tik) :: id_si, id_mix - if ( subroutine_timers ) call timer('semi_implicit_solver_alg') + if ( LPROF ) call start_timing( id_si, 'dynamics.solver' ) ! Input fields are r_def fields so preliminary work uses field_types mesh_id = state(igh_p)%get_mesh_id() @@ -669,14 +670,14 @@ contains end if ! Solve the semi-implicit operator - if ( subroutine_timers ) call timer('mixed_solver') + if ( LPROF ) call start_timing( id_mix, 'solver.mixed_solver' ) call log_event( "Gungho: mixed solve:", LOG_LEVEL_DEBUG ) ! Create field vectors out of field arrays call construct_solver_state(vector_inc, rhs_rsol, import_fields = .false.) call construct_solver_state(vector_rhs, rhs_rsol, import_fields = .true.) call vector_inc%set_scalar(0.0_r_def) call mixed_solver%apply(vector_inc, vector_rhs) - if ( subroutine_timers ) call timer('mixed_solver') + if ( LPROF ) call stop_timing( id_mix, 'solver.mixed_solver' ) ! Get the pressure increment inc_exner_rsol => vector_inc%get_field_from_position(isol_p) @@ -742,7 +743,7 @@ contains if ( write_moisture_diag ) & call moisture_conservation_alg( state(igh_d), mr, 'After solve' ) - if ( subroutine_timers ) call timer('semi_implicit_solver_alg') + if ( LPROF ) call stop_timing( id_si, 'dynamics.solver' ) end subroutine semi_implicit_solver_alg_step diff --git a/science/gungho/source/algorithm/solver/si_operators_alg_mod.x90 b/science/gungho/source/algorithm/solver/si_operators_alg_mod.x90 index 0b116dad8..6e35b6e35 100644 --- a/science/gungho/source/algorithm/solver/si_operators_alg_mod.x90 +++ b/science/gungho/source/algorithm/solver/si_operators_alg_mod.x90 @@ -35,9 +35,7 @@ module si_operators_alg_mod preconditioner_tridiagonal, & preconditioner_multigrid, & normalise - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer - + use timing_mod, only: start_timing, stop_timing, tik, LPROF use function_space_chain_mod, only: multigrid_function_space_chain, & w2_multigrid_function_space_chain, & wtheta_multigrid_function_space_chain @@ -193,7 +191,6 @@ contains type(function_space_type), pointer :: w3_fs => null() type(function_space_type), pointer :: wt_fs => null() - if ( subroutine_timers ) call timer('si_operators_alg:create') call log_event( "Gungho: creating si_operators", LOG_LEVEL_DEBUG ) if(l_multigrid) then @@ -282,8 +279,6 @@ contains end do nullify( w2_fs, w3_fs, wt_fs ) - if ( subroutine_timers ) call timer('si_operators_alg:create') - end subroutine create_si_operators !> @brief Explicitly reclaim memory from module scope variables @@ -471,8 +466,9 @@ contains ! needs to be one bigger than the required stencil_depth integer(kind=i_def), parameter :: req_stencil_depth = 1 integer(kind=i_def), parameter :: req_halo_depth = req_stencil_depth + 1 + integer(tik) :: id - if ( subroutine_timers ) call timer('si_operators_alg:compute') + if ( LPROF ) call start_timing( id, 'dynamics.compute_si_operators' ) call log_event( "Gungho: computing si_operators", LOG_LEVEL_DEBUG ) dt = real(model_clock%get_seconds_per_step(), r_def) @@ -823,8 +819,7 @@ contains nullify( chi, panel_id, m3_inv, div, w2_rmultiplicity, & mesh, reference_element, m2, u_normalisation, t_normalisation, & w2_mask, mesh ) - - if ( subroutine_timers ) call timer('si_operators_alg:compute') + if ( LPROF ) call stop_timing( id, 'dynamics.compute_si_operators' ) end subroutine compute_si_operators diff --git a/science/gungho/source/algorithm/timestepping/rk_alg_timestep_mod.x90 b/science/gungho/source/algorithm/timestepping/rk_alg_timestep_mod.x90 index 45605e512..d649c8eff 100644 --- a/science/gungho/source/algorithm/timestepping/rk_alg_timestep_mod.x90 +++ b/science/gungho/source/algorithm/timestepping/rk_alg_timestep_mod.x90 @@ -83,8 +83,8 @@ module rk_alg_timestep_mod use moist_dyn_mod, only: num_moist_factors, gas_law use mr_indices_mod, only: nummr - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use sci_field_minmax_alg_mod, only: log_field_minmax implicit none @@ -329,8 +329,9 @@ contains integer(kind=i_def) :: element_order_h, element_order_v integer(kind=i_def) :: nqp_h, nqp_v logical(kind=l_def) :: horizontal_face, vertical_face, cheap_update + integer(tik) :: id - if ( subroutine_timers ) call timer('rk_alg') + if ( LPROF ) call start_timing( id, 'rk_alg' ) qr => get_qr_fe() mesh => theta%get_mesh() reference_element => mesh%get_reference_element() @@ -464,7 +465,7 @@ contains nullify( geopotential, chi, panel_id, m3_inv, & mesh, reference_element, qr ) - if ( subroutine_timers ) call timer('rk_alg') + if ( LPROF ) call stop_timing( id, 'rk_alg' ) end subroutine run_step diff --git a/science/gungho/source/algorithm/timestepping/semi_implicit_timestep_alg_mod.X90 b/science/gungho/source/algorithm/timestepping/semi_implicit_timestep_alg_mod.X90 index 7aa360475..eb7dc2d09 100644 --- a/science/gungho/source/algorithm/timestepping/semi_implicit_timestep_alg_mod.X90 +++ b/science/gungho/source/algorithm/timestepping/semi_implicit_timestep_alg_mod.X90 @@ -48,8 +48,7 @@ module semi_implicit_timestep_alg_mod moisture_formulation, & moisture_formulation_dry, & exner_from_eos - use io_config_mod, only: subroutine_timers, & - write_conservation_diag, write_diag, & + use io_config_mod, only: write_conservation_diag, write_diag, & use_xios_io, diagnostic_frequency, & checkpoint_read use initialization_config_mod, only: init_option, & @@ -147,7 +146,7 @@ module semi_implicit_timestep_alg_mod #endif use cld_incs_mod, only: cld_incs_init, cld_incs_output - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use ageofair_alg_mod, only: ageofair_update implicit none @@ -662,8 +661,9 @@ contains logical(l_def) :: microphysics_casim logical(l_def) :: murk_lbc real(r_def) :: tau_r + integer(tik) :: id - if ( subroutine_timers ) call timer('semi_implicit_timestep_alg') + if ( LPROF ) call start_timing( id, 'semi_implicit_timestep' ) cast_dt = real(model_clock%get_seconds_per_step(), r_def) @@ -979,7 +979,7 @@ contains if ( limited_area .and. inner == 1 .and. outer == 1 ) then call lam_solver_lbc(self%state(igh_u), lbc_fields, prime_mesh_name) call calc_rhs_lbc(self%rhs_lbc, lbc_fields, model_clock, prime_mesh_name, & - tau_r, subroutine_timers) + tau_r) end if !-------------------------------------------------------------------- @@ -1156,7 +1156,7 @@ contains nullify( mm_wt, mm_vel ) - if ( subroutine_timers ) call timer('semi_implicit_timestep_alg') + if ( LPROF ) call stop_timing( id, 'semi_implicit_timestep' ) end subroutine run_step diff --git a/science/gungho/source/algorithm/transport/common/calc_dep_pts_alg_mod.x90 b/science/gungho/source/algorithm/transport/common/calc_dep_pts_alg_mod.x90 index 02150f9a1..775f52de7 100644 --- a/science/gungho/source/algorithm/transport/common/calc_dep_pts_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/calc_dep_pts_alg_mod.x90 @@ -28,7 +28,8 @@ module calc_dep_pts_alg_mod LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Configs use departure_points_config_mod, only: horizontal_method, & @@ -49,7 +50,6 @@ module calc_dep_pts_alg_mod vertical_limit_boundary, & vertical_limit_exponential, & vertical_sorting - use io_config_mod, only: subroutine_timers use transport_config_mod, only: dep_pt_stencil_extent, & calculate_detj, & calculate_detj_averaged, & @@ -158,8 +158,7 @@ contains type(r_tran_field_type) :: wind_adv type(r_tran_field_type) :: dep_wind type(r_tran_field_type) :: dep_wind_np1 - - if ( subroutine_timers ) call timer( 'transport.hori_dep_pts' ) + integer(tik) :: id ! Get function space, mesh, and Det(J) at W3 w2_fs => wind_n%get_function_space() @@ -186,6 +185,8 @@ contains ! Lagrangian approaches -------------------------------------------------- case ( horizontal_method_trapezoidal ) + + if ( LPROF ) call start_timing( id, 'transport.hori_dep_pts' ) call invoke( calc_departure_wind_kernel_type(dep_wind, wind_n, & detj_at_w3, 1), & calc_departure_wind_kernel_type(dep_wind_np1, wind_np1, & @@ -204,7 +205,11 @@ contains detj_at_w3, 1, & face_selector_ew, & face_selector_ns) ) + if ( LPROF ) call stop_timing( id, 'transport.hori_dep_pts' ) + case ( horizontal_method_midpoint ) + + if ( LPROF ) call start_timing( id, 'transport.hori_dep_pts' ) call invoke( calc_departure_wind_kernel_type(dep_wind, wind_n, & detj_at_w3, 1), & hori_dep_dist_midpoint_kernel_type(dep_dist, & @@ -219,9 +224,13 @@ contains detj_at_w3, 1, & face_selector_ew, & face_selector_ns) ) + if ( LPROF ) call stop_timing( id, 'transport.hori_dep_pts' ) ! Eulerian approaches ---------------------------------------------------- case ( horizontal_method_euler, horizontal_method_timeaverage ) + + if ( LPROF ) call start_timing( id, 'transport.hori_dep_pts' ) + ! Set the advecting wind based on the departure point method if ( horizontal_method == horizontal_method_euler ) then call invoke( setval_X(wind_adv, wind_np1) ) @@ -251,6 +260,8 @@ contains inc_min_aX(max_hori_dep, dep_dist) ) end if + if ( LPROF ) call stop_timing( id, 'transport.hori_dep_pts' ) + case ( horizontal_method_ffsl ) ! Use time-averaged wind cap_dep_points = (horizontal_limit == horizontal_limit_cap) @@ -280,8 +291,6 @@ contains nullify( w2_fs, w2h_fs, mesh, detj_at_w3, face_selector_ew, face_selector_ns ) - if ( subroutine_timers ) call timer( 'transport.hori_dep_pts' ) - end subroutine calc_hori_dep_pts !> @brief Calculates the horizontal FFSL departure points @@ -343,6 +352,9 @@ contains integer(kind=i_def) :: ndep logical(kind=l_def) :: cap_dep_points logical(kind=l_def) :: is_cubed_sphere + integer(tik) :: id + + if ( LPROF ) call start_timing( id, 'transport.hori_dep_pts' ) mesh => wind%get_mesh() face_selector_ew => get_face_selector_ew(mesh%get_id()) @@ -419,6 +431,8 @@ contains end if end if + if ( LPROF ) call stop_timing( id, 'transport.hori_dep_pts' ) + end subroutine calc_ffsl_hori_dep_pts @@ -472,9 +486,10 @@ contains type(function_space_type), pointer :: w2v_fs type(mesh_type), pointer :: mesh - real(kind=r_tran) :: half + real(kind=r_tran) :: half + integer(tik) :: id - if ( subroutine_timers ) call timer( 'transport.vert_dep_pts' ) + if ( LPROF ) call start_timing( id, 'transport.vert_dep_pts' ) ! Get function spaces mesh => wind_n%get_mesh() @@ -558,7 +573,7 @@ contains call log_event('Vertical departure point method not recognised', LOG_LEVEL_ERROR) end select - if ( subroutine_timers ) call timer( 'transport.vert_dep_pts' ) + if ( LPROF ) call stop_timing( id, 'transport.vert_dep_pts' ) end subroutine calc_vert_dep_pts diff --git a/science/gungho/source/algorithm/transport/common/end_of_transport_step_alg_mod.x90 b/science/gungho/source/algorithm/transport/common/end_of_transport_step_alg_mod.x90 index 34ee74e25..dc382d042 100644 --- a/science/gungho/source/algorithm/transport/common/end_of_transport_step_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/end_of_transport_step_alg_mod.x90 @@ -42,7 +42,6 @@ module end_of_transport_step_alg_mod get_face_selector_ns use integer_field_mod, only: integer_field_type use iterate_min_flux_kernel_mod, only: iterate_min_flux_kernel_type - use io_config_mod, only: subroutine_timers use limited_area_lbc_alg_mod, only: overwrite_blending_zone_rtran use log_mod, only: log_event, & log_scratch_space, & @@ -57,7 +56,8 @@ module end_of_transport_step_alg_mod use r_tran_operator_mod, only: r_tran_operator_type use split_transport_utils_mod, only: get_num_split_steps, & get_dry_config - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_config_mod, only: dry_field_name, & min_val_abs_tol, & min_val_max_iterations, & @@ -126,8 +126,6 @@ contains logical(kind=l_def) :: do_overwrite type(r_tran_field_type), pointer :: field_start - if ( subroutine_timers ) call timer('transport.end_of_transport') - mesh => field_np1%get_mesh() ! Determine whether this is the final split step @@ -172,8 +170,6 @@ contains call log_field_minmax( LOG_LEVEL_DEBUG, 'field_np1: end_of_advective_step', field_np1) - if ( subroutine_timers ) call timer('transport.end_of_transport') - end subroutine end_of_advective_step_alg !> @brief Common end-of-step code for conservative transport schemes @@ -232,8 +228,7 @@ contains real(kind=r_tran) :: adv_dt real(kind=r_tran) :: acceptable_min real(kind=r_tran) :: field_min, field_max - - if ( subroutine_timers ) call timer('transport.end_of_transport') + integer(tik) :: id_iter ! Extract transport runtime mesh => field_np1%get_mesh() @@ -274,7 +269,7 @@ contains if (enforce_min_value .and. min_val_method == min_val_method_iterative) then - if ( subroutine_timers ) call timer('transport.iterative_min_val') + if ( LPROF ) call start_timing( id_iter, 'transport.iterative_min_val' ) div => get_directional_im3_div_r_tran(mesh_id, direction_3d) ! TODO #3706: the flux limiter should use r_tran precision @@ -313,7 +308,7 @@ contains end if end do - if ( subroutine_timers ) call timer('transport.iterative_min_val') + if ( LPROF ) call stop_timing( id_iter, 'transport.iterative_min_val' ) else if (operators == operators_fem) then ! Finite element transport, so need full divergence operator @@ -390,8 +385,6 @@ contains call log_field_minmax( LOG_LEVEL_DEBUG, 'field_np1: end_of_conservative_step', field_np1) - if ( subroutine_timers ) call timer('transport.end_of_transport') - end subroutine end_of_conservative_step_alg !> @brief Common end-of-step code for consistent transport schemes @@ -490,8 +483,7 @@ contains real(kind=r_tran) :: acceptable_min real(kind=r_tran) :: field_min, field_max logical(kind=l_def) :: to_compute_field_np1 - - if ( subroutine_timers ) call timer('transport.end_of_transport') + integer(tik) :: id_iter ! Extract transport runtime prime_extrusion_mesh => field_np1%get_mesh() @@ -532,8 +524,6 @@ contains (trim(transport_metadata%get_name()) == 'potential_temperature' .or. & trim(transport_metadata%get_name()) == 'theta')) then - if ( subroutine_timers ) call timer('transport.theta_dispersion') - shifted_mesh => mesh_collection%get_mesh(prime_extrusion_mesh, SHIFTED) sh_w3_fs => function_space_collection%get_fs(shifted_mesh, 0, 0, W3) rmultiplicity_shifted => get_rmultiplicity_fv(flux_function_space, shifted_mesh%get_id()) @@ -571,7 +561,6 @@ contains face_selector_ns), & inc_X_plus_Y(flux, flux_correction) ) - if ( subroutine_timers ) call timer('transport.theta_dispersion') end if ! ------------------------------------------------------------------------ ! @@ -644,7 +633,7 @@ contains call build_up_flux(sum_flux, flux, transport_counter, transport_metadata) if (enforce_min_value .and. min_val_method == min_val_method_iterative) then - if ( subroutine_timers ) call timer('transport.iterative_min_val') + if ( LPROF ) call start_timing( id_iter, 'transport.iterative_min_val' ) select case( mr_function_space ) case ( W3 ) @@ -683,7 +672,7 @@ contains end if end do - if ( subroutine_timers ) call timer('transport.iterative_min_val') + if ( LPROF ) call stop_timing( id_iter, 'transport.iterative_min_val' ) else ! Compute updated field using flux for whole transport step @@ -766,8 +755,6 @@ contains call log_field_minmax( LOG_LEVEL_DEBUG, 'field_np1: end_of_consistent_step', field_np1) - if ( subroutine_timers ) call timer('transport.end_of_transport') - end subroutine end_of_consistent_step_alg !> @brief Build up the mass flux used over a full conservative transport step @@ -809,8 +796,6 @@ contains logical(kind=l_def) :: is_flux_3d logical(kind=l_def) :: is_flux_split - if ( subroutine_timers ) call timer('transport.build_up_flux') - ! Don't know which function space the fluxes are in -- add up each mesh => sum_flux%get_mesh() mesh_id = mesh%get_id() @@ -837,6 +822,7 @@ contains ! General case for any splitting else + call sum_hori_flux%initialise(w2h_fs) call sum_vert_flux%initialise(w2v_fs) @@ -890,8 +876,6 @@ contains end if end if - if ( subroutine_timers ) call timer('transport.build_up_flux') - end subroutine build_up_flux end module end_of_transport_step_alg_mod diff --git a/science/gungho/source/algorithm/transport/common/flux_precomputations_mod.x90 b/science/gungho/source/algorithm/transport/common/flux_precomputations_mod.x90 index 993b71d38..94f81a1f8 100644 --- a/science/gungho/source/algorithm/transport/common/flux_precomputations_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/flux_precomputations_mod.x90 @@ -47,7 +47,6 @@ module flux_precomputations_alg_mod use sci_geometric_constants_mod, only: get_face_selector_ew, & get_face_selector_ns use integer_field_mod, only: integer_field_type - use io_config_mod, only: subroutine_timers use lfric_mpi_mod, only: global_mpi use limited_area_lbc_alg_mod, only: overwrite_blending_zone_rtran use local_mesh_mod, only: local_mesh_type @@ -74,7 +73,8 @@ module flux_precomputations_alg_mod get_fraction_from_idx, & get_fraction_idx, & get_num_split_steps - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_config_mod, only: panel_edge_treatment, & panel_edge_treatment_extended_mesh,& ffsl_inner_order, & @@ -277,8 +277,9 @@ contains type(r_tran_field_type) :: flux_vert type(r_tran_field_type), pointer :: flux_ptr type(r_tran_field_type), target :: ref_flux_restricted + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.flux_precomp_init') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp_init' ) self%splitting = splitting self%num_substeps = num_substeps @@ -562,7 +563,7 @@ contains self%transporting_wind => wind self%dt = dt - if ( subroutine_timers ) call timer('transport.flux_precomp_init') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp_init' ) end subroutine flux_precomputations_initialiser @@ -645,8 +646,9 @@ contains type(function_space_type), pointer :: w2_fs type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.flux_precomp_init') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp_init' ) ! Checks ------------------------------------------------------------------ ! Is the reference flux on a prime extrusion? @@ -718,7 +720,7 @@ contains call invoke( setval_X(self%ref_flux(1, step), ref_flux) ) end if - if ( subroutine_timers ) call timer('transport.flux_precomp_init') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp_init' ) end subroutine initialise_step @@ -839,6 +841,7 @@ contains type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns type(r_tran_field_type), pointer :: ref_flux + integer(tik) :: id ! If substepping, step can exceed num_steps, so take that into account here ! This is because, when transporting by the wind field (and using unity as @@ -867,7 +870,7 @@ contains face_selector_ew => get_face_selector_ew(self%mesh_ids(2)) face_selector_ns => get_face_selector_ns(self%mesh_ids(2)) - if ( subroutine_timers ) call timer('transport.get_ref_flux') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) ! Transform fluxes to the shifted mesh, with case depending on fs_id select case (fs_id) @@ -894,7 +897,7 @@ contains self%ref_flux(1, step_idx)) ) end select - if ( subroutine_timers ) call timer('transport.get_ref_flux') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end if ! Point to existing field @@ -940,6 +943,7 @@ contains type(r_tran_field_type), pointer :: ref_field type(r_tran_field_type), pointer :: detj_w3 character(len=str_def) :: field_name + integer(tik) :: id mesh_idx = self%idx_from_mesh_id(mesh_id) @@ -961,7 +965,7 @@ contains ! Obtain reference field from mass ref_mass => self%get_ref_mass(mesh_id, step) - if ( subroutine_timers ) call timer('transport.get_ref_field') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) call self%ref_field(mesh_idx, step)%initialise(w3_fs, halo_depth=halo_depth) @@ -973,7 +977,7 @@ contains detj_w3) ) end if - if ( subroutine_timers ) call timer('transport.get_ref_field') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end if ! Return existing field @@ -1045,6 +1049,7 @@ contains type(r_tran_field_type) :: tmp_mass type(r_tran_field_type) :: tmp_field character(len=str_def) :: field_name + integer(tik) :: id mesh_idx = self%idx_from_mesh_id(mesh_id) @@ -1079,7 +1084,7 @@ contains ref_flux => self%get_ref_flux(mesh_id, step-1) call increment%initialise(w3_fs) - if ( subroutine_timers ) call timer('transport.get_ref_mass') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) ! Take divergence of flux to get increment fs_id = ref_flux%which_function_space() @@ -1140,14 +1145,14 @@ contains depth=transport_boundary_depth) end if - if ( subroutine_timers ) call timer('transport.get_ref_mass') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) ! ---------------------------------------------------------------------- ! ! 2. The density from this step (multiplied by cell volumes) ! ---------------------------------------------------------------------- ! else if (self%ref_field(mesh_idx, step)%is_initialised()) then - if ( subroutine_timers ) call timer('transport.get_ref_mass') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) detj_w3 => get_detj_at_w3_r_tran(mesh_id) if (panel_edge_treatment == panel_edge_treatment_extended_mesh) then call invoke_deep_X_times_Y(self%ref_mass(mesh_idx, step), & @@ -1157,13 +1162,13 @@ contains self%ref_field(mesh_idx, step), detj_w3) ) end if - if ( subroutine_timers ) call timer('transport.get_ref_mass') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) ! ---------------------------------------------------------------------- ! ! 3. If on the shifted mesh, obtain the mass by shifting the mass ! ---------------------------------------------------------------------- ! else if (mesh_idx == 2) then - if ( subroutine_timers ) call timer('transport.get_ref_mass') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) ref_mass_prime => self%get_ref_mass(self%mesh_ids(1), step, negative_check_flag) if (panel_edge_treatment == panel_edge_treatment_extended_mesh) then ! Original field has already been remapped, so can perform a "deep" @@ -1176,7 +1181,7 @@ contains call invoke( shift_mass_w3_kernel_type(self%ref_mass(2, step), & ref_mass_prime) ) end if - if ( subroutine_timers ) call timer('transport.get_ref_mass') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end if ! Check if the computed reference mass is negative ----------------------- @@ -1224,6 +1229,7 @@ contains type(r_tran_field_type), pointer :: ref_mass type(r_tran_field_type), pointer :: detj_w3 type(r_tran_field_type), pointer :: ref_field + integer(tik) :: id ! If substepping, step can exceed num_steps, so take that into account here step_idx = MOD(step - 1, self%num_steps) + 1 @@ -1246,7 +1252,7 @@ contains detj_w3 => get_detj_at_w3_r_tran(mesh_id) w3_fs => function_space_collection%get_fs(mesh, 0, 0, W3) - if ( subroutine_timers ) call timer('transport.get_ref_field_xy') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) call self%ref_field_x(mesh_idx, step_idx)%initialise(w3_fs, halo_depth=halo_depth) @@ -1257,7 +1263,7 @@ contains call invoke( X_divideby_Y(self%ref_field_x(mesh_idx, step_idx), & ref_mass, detj_w3) ) end if - if ( subroutine_timers ) call timer('transport.get_ref_field_xy') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end if ! Return existing field @@ -1288,6 +1294,7 @@ contains type(r_tran_field_type), pointer :: ref_mass type(r_tran_field_type), pointer :: detj_w3 type(r_tran_field_type), pointer :: ref_field + integer(tik) :: id ! If substepping, step can exceed num_steps, so take that into account here step_idx = MOD(step - 1, self%num_steps) + 1 @@ -1310,7 +1317,7 @@ contains detj_w3 => get_detj_at_w3_r_tran(mesh_id) w3_fs => function_space_collection%get_fs(mesh, 0, 0, W3) - if ( subroutine_timers ) call timer('transport.get_ref_field_xy') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) call self%ref_field_y(mesh_idx, step_idx)%initialise(w3_fs, halo_depth=halo_depth) @@ -1321,7 +1328,7 @@ contains call invoke( X_divideby_Y(self%ref_field_y(mesh_idx, step_idx), & ref_mass, detj_w3) ) end if - if ( subroutine_timers ) call timer('transport.get_ref_field_xy') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end if ! Return existing field @@ -1642,6 +1649,7 @@ contains real(kind=r_tran) :: dep_min, dep_max type(mesh_type), pointer :: mesh type(r_tran_field_type), pointer :: dep_dist + integer(tik) :: id ! If substepping, step can exceed num_steps, so take that into account here step_idx = MOD(step - 1, self%num_steps) + 1 @@ -1666,7 +1674,7 @@ contains mesh => mesh_collection%get_mesh(mesh_id) dep_dist => self%get_dep_dist(mesh_id, step, outer_step_local) - if ( subroutine_timers ) call timer('transport.get_dep_stencil_extent') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) ! We can shorten the stencil extent to the Courant number call get_field_minmax(dep_dist, dep_min, dep_max) @@ -1684,7 +1692,7 @@ contains self%max_stencil_extent_computed = .true. end if - if ( subroutine_timers ) call timer('transport.get_dep_stencil_extent') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end if ! INNER STEP EXTENTS ------------------------------------------------------- @@ -1703,7 +1711,7 @@ contains mesh => mesh_collection%get_mesh(mesh_id) dep_dist => self%get_dep_dist(mesh_id, step, outer_step_local) - if ( subroutine_timers ) call timer('transport.get_dep_stencil_extent') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) ! We can shorten the stencil extent to the Courant number call get_field_minmax(dep_dist, dep_min, dep_max) @@ -1721,7 +1729,7 @@ contains self%max_stencil_extent_computed = .true. end if - if ( subroutine_timers ) call timer('transport.get_dep_stencil_extent') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end if end function get_dep_stencil_extent @@ -1809,7 +1817,7 @@ contains type(r_tran_field_type) :: increment_y type(r_tran_field_type) :: tmp_mass type(r_tran_field_type) :: tmp_field - + integer(tik) :: id ! If substepping, step can exceed num_steps, so take that into account here step_idx = MOD(step - 1, self%num_steps) + 1 mesh_idx = self%idx_from_mesh_id(mesh_id) @@ -1835,7 +1843,7 @@ contains ref_flux => self%get_ref_flux(mesh_id, step) w3_fs => function_space_collection%get_fs(mesh, 0, 0, W3) - if ( subroutine_timers ) call timer('transport.get_ref_mass_xy') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) call self%ref_mass_x(mesh_idx, step_idx)%initialise(w3_fs, halo_depth=halo_depth) call self%ref_mass_y(mesh_idx, step_idx)%initialise(w3_fs, halo_depth=halo_depth) @@ -1891,7 +1899,7 @@ contains ) end if - if ( subroutine_timers ) call timer('transport.get_ref_mass_xy') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end subroutine compute_ref_mass_x_and_y @@ -1923,6 +1931,7 @@ contains type(r_tran_field_type), pointer :: ref_mass type(r_tran_field_type), pointer :: ref_flux character(len=str_def) :: field_name + integer(tik) :: id ! If substepping, step can exceed num_steps, so take that into account here step_idx = MOD(step - 1, self%num_steps) + 1 @@ -1937,7 +1946,7 @@ contains end if ref_flux => self%get_ref_flux(mesh_id, step) - if ( subroutine_timers ) call timer('transport.compute_dep_dists') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) w2_fs => ref_flux%get_function_space() call self%dep_dist(mesh_idx, step_idx)%initialise(w2_fs) @@ -1979,7 +1988,7 @@ contains ) end if - if ( subroutine_timers ) call timer('transport.compute_dep_dists') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end subroutine compute_dep_dist_inner @@ -2011,6 +2020,7 @@ contains type(r_tran_field_type), pointer :: ref_mass_x type(r_tran_field_type), pointer :: ref_mass_y character(len=str_def) :: field_name + integer(tik) :: id ! If substepping, step can exceed num_steps, so take that into account here step_idx = MOD(step - 1, self%num_steps) + 1 @@ -2021,7 +2031,7 @@ contains ref_mass_x => self%get_ref_mass_x(mesh_id, step) ref_mass_y => self%get_ref_mass_y(mesh_id, step) - if ( subroutine_timers ) call timer('transport.compute_dep_dists') + if ( LPROF ) call start_timing( id, 'transport.flux_precomp' ) if (direction /= direction_h) then write(log_scratch_space, '(A,I8,A)') & @@ -2059,7 +2069,7 @@ contains ) end if - if ( subroutine_timers ) call timer('transport.compute_dep_dists') + if ( LPROF ) call stop_timing( id, 'transport.flux_precomp' ) end subroutine compute_dep_dist_outer @@ -2136,12 +2146,21 @@ contains end if write(log_scratch_space, '(A,E16.8,A)') & - 'Negative or tiny value ', field_min, ' detected in ' // & - 'transport reference field ' // adjustl(trim(field_name)) // '. ' // & - 'This makes it impossible to find sensible departure distances. ' // & - 'Most likely the input transporting wind to the transport ' // & - 'scheme has a maximum Lipschitz number that exceeds 1 somewhere, ' // & - 'so check these values. Stopping model now to fail gracefully' + 'The transport scheme has a detected negative or tiny value ', & + field_min, 'in the transport reference field ' // & + adjustl(trim(field_name)) // '. This makes it impossible to find ' // & + 'sensible departure distances for (Flux Form) Semi-Lagrangian ' // & + 'transport. Stopping now to fail gracefully.' // & + NEW_LINE('A') // NEW_LINE('A') // & + 'This is a common way for the model to fail. Most likely the ' // & + 'transporting wind passed to the transport scheme has some ' // & + 'unphysical values, and the corresponding maximum Lipschitz ' // & + 'number exceeds 1 somewhere, so check these values in the log ' // & + 'above, which may also indicate the geographical location of ' // & + 'the issue.' // & + NEW_LINE('A') // NEW_LINE('A') // & + 'If this failure has occurred in the first timestep, it can ' // & + 'signify issues with the initial conditions or ancillaries.' call log_event(log_scratch_space, LOG_LEVEL_ERROR) end if diff --git a/science/gungho/source/algorithm/transport/common/panel_edge_remap_alg_mod.x90 b/science/gungho/source/algorithm/transport/common/panel_edge_remap_alg_mod.x90 index 77eedd2e8..7d8f58959 100644 --- a/science/gungho/source/algorithm/transport/common/panel_edge_remap_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/panel_edge_remap_alg_mod.x90 @@ -13,8 +13,7 @@ module panel_edge_remap_alg_mod use r_tran_field_mod, only: r_tran_field_type use integer_field_mod, only: integer_field_type use mesh_mod, only: mesh_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use function_space_mod, only: function_space_type use transport_config_mod, only: ffsl_inner_order, ffsl_outer_order, & panel_edge_high_order @@ -80,9 +79,9 @@ contains integer(kind=i_def) :: mesh_id, ndata integer(kind=i_def) :: max_halo_depth, cross_depth integer(kind=i_def) :: field_read_depth, remap_depth + integer(kind=tik) :: id - - if ( subroutine_timers ) call timer('transport.panel_edge_remap') + if ( LPROF ) call start_timing( id, 'transport.panel_edge_remap' ) mesh => field_for_x%get_mesh() mesh_id = mesh%get_id() @@ -161,7 +160,7 @@ contains ffsl_depth & ) - if ( subroutine_timers ) call timer('transport.panel_edge_remap') + if ( LPROF ) call stop_timing( id, 'transport.panel_edge_remap' ) end subroutine panel_edge_remap_alg diff --git a/science/gungho/source/algorithm/transport/common/predictors_alg_mod.x90 b/science/gungho/source/algorithm/transport/common/predictors_alg_mod.x90 index 6af318e78..c8d977a1a 100644 --- a/science/gungho/source/algorithm/transport/common/predictors_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/predictors_alg_mod.x90 @@ -22,6 +22,8 @@ module predictors_alg_mod use field_mod, only: field_type use model_clock_mod, only: model_clock_type use operator_mod, only: operator_type + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Configurations use derived_config_mod, only: bundle_size @@ -79,10 +81,14 @@ contains real(kind=r_def) :: df_min real(kind=r_def) :: df_max real(kind=r_def) :: cast_dt + ! Timing identifier + integer(tik) :: id ! Divergence operator type(operator_type), pointer :: im3_div => null() + if ( LPROF ) call start_timing( id, "dynamics.transport_predictors") + ! Predictor of the wind field (u-beta*dt*rhs) if ( .not. si_momentum_equation ) then if (horizontal_transport_predictor) then @@ -133,6 +139,8 @@ contains nullify( im3_div ) end if + if ( LPROF ) call stop_timing( id, "dynamics.transport_predictors") + end subroutine predictors_alg end module predictors_alg_mod diff --git a/science/gungho/source/algorithm/transport/common/remap_on_extended_mesh_alg_mod.x90 b/science/gungho/source/algorithm/transport/common/remap_on_extended_mesh_alg_mod.x90 index 87cc7ce82..ea01e52fe 100644 --- a/science/gungho/source/algorithm/transport/common/remap_on_extended_mesh_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/remap_on_extended_mesh_alg_mod.x90 @@ -14,10 +14,8 @@ module remap_on_extended_mesh_alg_mod use integer_field_mod, only: integer_field_type use mesh_mod, only: mesh_type use psykal_lite_transport_mod, only: invoke_remap_on_extended_mesh_kernel_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use function_space_mod, only: function_space_type - use check_configuration_mod, only: get_required_stencil_depth use transport_constants_mod, only: get_extended_mesh_weights, & get_extended_mesh_indices, & ext_mesh_stencil_depth @@ -64,9 +62,10 @@ contains integer(kind=i_def) :: ndata integer(kind=i_def) :: depth type(r_tran_field_type) :: field_to_remap + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.remap_extended_mesh') + if ( LPROF ) call start_timing( id, 'transport.remap_extended_mesh' ) mesh => field%get_mesh() panel_id => get_panel_id(mesh%get_id()) @@ -76,7 +75,7 @@ contains ndata = fs%get_ndata() ! Ensure remapping depth is not larger than the halo depth - depth = min( depth_in, get_required_stencil_depth() ) + depth = min( depth_in, mesh%get_halo_depth() ) ! Both the field to be remapped and the remapped field need to be ! created with the full size halo. For the field to be remapped ! this is due to the interpolation parallel to a panel boundary @@ -105,7 +104,7 @@ contains depth ) nullify(mesh, fs, panel_id) - if ( subroutine_timers ) call timer('transport.remap_extended_mesh') + if ( LPROF ) call stop_timing( id, 'transport.remap_extended_mesh' ) end subroutine remap_on_extended_mesh diff --git a/science/gungho/source/algorithm/transport/common/transport_counter_mod.x90 b/science/gungho/source/algorithm/transport/common/transport_counter_mod.x90 index 6e7dbe6a6..b40c2cc84 100644 --- a/science/gungho/source/algorithm/transport/common/transport_counter_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/transport_counter_mod.x90 @@ -40,6 +40,7 @@ module transport_counter_mod contains procedure, public :: initialise + procedure, public :: adj_initialise procedure, public :: get_field_n procedure, public :: set_field_n procedure, public :: get_flux @@ -51,6 +52,7 @@ module transport_counter_mod procedure, public :: get_num_split_steps_per_substep procedure, public :: get_dt_substep procedure, public :: get_outer_iteration + procedure, public :: dec_split_step_counter procedure, public :: inc_split_step_counter procedure, public :: inc_substep_counter procedure, public :: apply_cheap_update @@ -98,18 +100,70 @@ contains self%split_step_of_substep_counter = 1 self%substep_counter = 1 - if (allocated(self%flux)) deallocate(self%flux) - equation_form = transport_metadata%get_equation_form() ! Allocate arrays for dry fields if (equation_form == equation_form_conservative & - .or. equation_form == equation_form_consistent) then - allocate(self%flux(self%num_split_steps_per_substep-1)) + .or. equation_form == equation_form_consistent) then + if ( .not. allocated(self%flux)) then + allocate(self%flux(self%num_split_steps_per_substep-1)) + end if end if end subroutine initialise + !> @brief Initialises the transport_counter object, allocating flux fields + !! if necessary, ready for the adjoint model simulation + !> @details This is the same as initialise, but it prepares the code to be + !! run in reverse order, with the counter decreasing instead of + !! increasing. + !> @param[in] transport_metadata Object containing metadata describing + !! the options for transporting a variable + !> @param[in] dt_substep The time interval for a single substep + !> @param[in] num_substeps The number of total transport substeps to be + !! performed + !> @param[in] outer Optional, current iteration of the outer + !! loop of the semi-implicit time step + subroutine adj_initialise(self, transport_metadata, dt_substep, num_substeps, outer) + + implicit none + + class(transport_counter_type), intent(inout) :: self + type(transport_metadata_type), intent(in) :: transport_metadata + real(kind=r_tran), intent(in) :: dt_substep + integer(kind=i_def), intent(in) :: num_substeps + integer(kind=i_def), optional, intent(in) :: outer + + integer(kind=i_def) :: equation_form + + self%dt_substep = dt_substep + self%num_substeps = num_substeps + self%num_split_steps_per_substep = get_num_split_steps(transport_metadata%get_splitting()) + self%num_split_steps_per_whole_step = self%num_substeps * self%num_split_steps_per_substep + + if (present(outer)) then + self%outer = outer + else + self%outer = 0 + end if + + ! Initialise step counters to the last values (NOT 1) + self%split_step_of_whole_step_counter = self%num_split_steps_per_whole_step + self%split_step_of_substep_counter = self%num_split_steps_per_substep + self%substep_counter = num_substeps + + equation_form = transport_metadata%get_equation_form() + + ! Allocate arrays for dry fields + if (equation_form == equation_form_conservative & + .or. equation_form == equation_form_consistent) then + if ( .not. allocated(self%flux)) then + allocate(self%flux(self%num_split_steps_per_substep-1)) + end if + end if + + end subroutine adj_initialise + !> Public finalise method for the transport_counter subroutine finalise(self) @@ -314,6 +368,18 @@ contains ! ============================================================================ ! ! UTILITIES ! ============================================================================ ! + !> @brief Decreases the counter of transport split steps (for adjoint model) + subroutine dec_split_step_counter(self) + + implicit none + + class(transport_counter_type), target, intent(inout) :: self + + self%split_step_of_substep_counter = self%split_step_of_substep_counter - 1 + self%split_step_of_whole_step_counter = self%split_step_of_whole_step_counter - 1 + + end subroutine dec_split_step_counter + !> @brief Increments the counter of transport split steps subroutine inc_split_step_counter(self) diff --git a/science/gungho/source/algorithm/transport/common/transport_metadata_mod.F90 b/science/gungho/source/algorithm/transport/common/transport_metadata_mod.F90 index 6b0e596f2..03026c745 100644 --- a/science/gungho/source/algorithm/transport/common/transport_metadata_mod.F90 +++ b/science/gungho/source/algorithm/transport/common/transport_metadata_mod.F90 @@ -408,7 +408,11 @@ end function get_ffsl_vertical_order !> @param[in] adaptive_splitting Whether to use adaptive splitting. If !! true, sets the splitting to the splitting argument. !> @param[in] splitting The splitting to use if adaptive_splitting is true - subroutine update_metadata(self, outer, adaptive_splitting, splitting) + !> @param[in] make_tracers_advective Whether to set the equation form to be + !! advective when unable to compute departure points + !! for consistent tracers + subroutine update_metadata(self, outer, adaptive_splitting, splitting, & + make_tracers_advective) use timestepping_config_mod, only: outer_iterations use transport_config_mod, only: si_outer_transport, & @@ -419,6 +423,7 @@ subroutine update_metadata(self, outer, adaptive_splitting, splitting) dry_field_name use transport_enumerated_types_mod, & only: equation_form_advective, & + equation_form_consistent, & split_method_ffsl, & split_method_sl, & monotone_qm_pos, & @@ -431,6 +436,7 @@ subroutine update_metadata(self, outer, adaptive_splitting, splitting) integer(kind=i_def), intent(in) :: outer logical(kind=l_def), intent(in) :: adaptive_splitting integer(kind=i_def), intent(in) :: splitting + logical(kind=l_def), intent(in) :: make_tracers_advective if (si_outer_transport /= si_outer_transport_none & .and. outer < outer_iterations & @@ -470,6 +476,12 @@ subroutine update_metadata(self, outer, adaptive_splitting, splitting) self%splitting = splitting end if + if ( make_tracers_advective .and. & + self%equation_form == equation_form_consistent ) then + ! Set equation form to be advective + self%equation_form = equation_form_advective + end if + end subroutine update_metadata !> @brief Reset the metadata to its original values diff --git a/science/gungho/source/algorithm/transport/common/wind_precomputations_mod.x90 b/science/gungho/source/algorithm/transport/common/wind_precomputations_mod.x90 index 0578f128b..0e4a4e823 100644 --- a/science/gungho/source/algorithm/transport/common/wind_precomputations_mod.x90 +++ b/science/gungho/source/algorithm/transport/common/wind_precomputations_mod.x90 @@ -35,7 +35,6 @@ module wind_precomputations_alg_mod use sci_geometric_constants_mod, only: get_face_selector_ew, & get_face_selector_ns use integer_field_mod, only: integer_field_type - use io_config_mod, only: subroutine_timers use local_mesh_mod, only: local_mesh_type use log_mod, only: log_event, & log_scratch_space, & @@ -52,7 +51,8 @@ module wind_precomputations_alg_mod get_fraction_from_idx, & get_fraction_idx, & get_num_split_steps - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_enumerated_types_mod, only: direction_h, & direction_v, & direction_3d @@ -188,6 +188,7 @@ contains type(mesh_type), pointer :: mesh integer(kind=i_def) :: num_meshes integer(kind=i_def) :: num_fractions + integer(tik) :: id type(function_space_type), pointer :: w2_fs type(function_space_type), pointer :: w2h_fs @@ -195,7 +196,7 @@ contains type(integer_field_type), pointer :: face_selector_ew type(integer_field_type), pointer :: face_selector_ns - if ( subroutine_timers ) call timer('transport.wind_precomp_init') + if ( LPROF ) call start_timing( id, 'transport.wind_precomp_init' ) ! ------------------------------------------------------------------------ ! ! Get correct element order arguments @@ -347,7 +348,7 @@ contains self%courant_computed(:) = .false. self%is_initialised_flag = .true. - if ( subroutine_timers ) call timer('transport.wind_precomp_init') + if ( LPROF ) call stop_timing( id, 'transport.wind_precomp_init' ) end subroutine wind_precomputations_initialiser @@ -367,8 +368,12 @@ contains implicit none + integer(tik) :: id + class(wind_precomputations_type), intent(inout) :: self + if ( LPROF ) call start_timing( id, 'transport.wind_precomp_final' ) + self%is_initialised_flag = .false. if ( allocated( self%mesh_ids ) ) deallocate( self%mesh_ids ) if ( allocated( self%wind_n ) ) deallocate( self%wind_n ) @@ -403,6 +408,8 @@ contains if ( allocated( self%dep_stencil_extent ) ) deallocate( self%dep_stencil_extent ) if ( allocated( self%split_ffsl_precomputations ) ) deallocate( self%split_ffsl_precomputations ) + if ( LPROF ) call stop_timing( id, 'transport.wind_precomp_final' ) + end subroutine finalise ! ============================================================================ ! @@ -813,6 +820,7 @@ contains integer(kind=i_def) :: stencil_extent real(kind=r_tran) :: dt_split_step real(kind=r_tran) :: dep_min, dep_max + integer(tik) :: id ! If departure points calculated using "FFSL" method, get these from the ! flux precomputations object @@ -826,7 +834,7 @@ contains ! Otherwise, the departure points are those stored in this object else - if ( subroutine_timers ) call timer('transport.dep_dist_reset_unity') + if ( LPROF ) call start_timing( id, 'transport.wind_precomp' ) ! Check if they have been computed, based on if they are initialised mesh_idx = self%idx_from_mesh_id(mesh_id) @@ -861,7 +869,7 @@ contains dep_dist_xy => self%dep_dist_xy(mesh_idx, frac_idx) - if ( subroutine_timers ) call timer('transport.dep_dist_reset_unity') + if ( LPROF ) call stop_timing( id, 'transport.wind_precomp' ) end if end function get_dep_dist_xy @@ -895,6 +903,7 @@ contains integer(kind=i_def) :: frac real(kind=r_tran) :: dt_split_step logical(kind=l_def) :: compute_dep_cfl + integer(tik) :: id ! If departure points calculated using "FFSL" method, get these from the ! flux precomputations object @@ -905,7 +914,7 @@ contains ! Otherwise, the departure points are those stored in this object else - if ( subroutine_timers ) call timer('transport.dep_dist_reset_unity') + if ( LPROF ) call start_timing( id, 'transport.wind_precomp' ) ! Check if they have been computed, based on if they are initialised mesh_idx = self%idx_from_mesh_id(mesh_id) @@ -931,7 +940,7 @@ contains dep_dist_z => self%dep_dist_z(mesh_idx, frac_idx) - if ( subroutine_timers ) call timer('transport.dep_dist_reset_unity') + if ( LPROF ) call stop_timing( id, 'transport.wind_precomp' ) end if end function get_dep_dist_z @@ -1253,12 +1262,13 @@ contains type(r_tran_field_type) :: dep_dist_z type(r_tran_field_type) :: frac_vert_wind logical(kind=l_def) :: compute_cfl_dep + integer(tik) :: id mesh_idx = self%idx_from_mesh_id(mesh_id) ! Has the field already been computed? If not, compute it now if (.not. self%dep_courant_vert(mesh_idx)%is_initialised()) then - if ( subroutine_timers ) call timer('transport.dep_dist_courant') + if ( LPROF ) call start_timing( id, 'transport.wind_precomp' ) ! Calculate vertical departure distance mesh => mesh_collection%get_mesh(mesh_id) @@ -1278,7 +1288,7 @@ contains self%wind_n(mesh_idx), self%wind_np1(mesh_idx), self%dt_substep, & compute_cfl_dep & ) - if ( subroutine_timers ) call timer('transport.dep_dist_courant') + if ( LPROF ) call stop_timing( id, 'transport.wind_precomp' ) end if dep_courant_vert => self%dep_courant_vert(mesh_idx) @@ -1376,6 +1386,7 @@ contains real(kind=r_tran) :: min_courant_hori, max_courant_hori real(kind=r_tran) :: min_courant_3d, max_courant_3d real(kind=r_tran) :: cfl_limit + integer(tik) :: id mesh => mesh_collection%get_mesh(mesh_id) mesh_idx = self%idx_from_mesh_id(mesh_id) @@ -1397,7 +1408,7 @@ contains face_selector_ns => get_face_selector_ns(mesh_id) wind_3d => self%get_wind(mesh_id, direction_3d) - if ( subroutine_timers ) call timer('transport.compute_courant') + if ( LPROF ) call start_timing( id, 'transport.wind_precomp' ) ! ------------------------------------------------------------------------ ! ! Determine Courant number field @@ -1509,7 +1520,7 @@ contains self%courant_computed(mesh_idx) = .true. - if ( subroutine_timers ) call timer('transport.compute_courant') + if ( LPROF ) call stop_timing( id, 'transport.wind_precomp' ) end subroutine compute_courant @@ -1543,6 +1554,7 @@ contains type(r_tran_field_type), pointer :: dep_dist_z type(r_tran_field_type), pointer :: coeffs(:) type(integer_field_type), pointer :: sl_indices(:) + integer(tik) :: id mesh => mesh_collection%get_mesh(mesh_id) fs => function_space_collection%get_fs(mesh, 0, 0, space) @@ -1552,7 +1564,7 @@ contains frac_idx = get_fraction_idx(splitting, step) dep_dist_z => self%get_dep_dist_z(mesh_id, splitting, step) - if ( subroutine_timers ) call timer('transport.compute_sl_coeffs') + if ( LPROF ) call start_timing( id, 'transport.wind_precomp' ) ! Points to appropriate coefficients and indices --------------------------- select case (space) @@ -1624,7 +1636,7 @@ contains ! Compute coefficients ----------------------------------------------------- call compute_sl_coefficients_alg(coeffs, sl_indices, dep_dist_z, order) - if ( subroutine_timers ) call timer('transport.compute_sl_coeffs') + if ( LPROF ) call stop_timing( id, 'transport.wind_precomp' ) end subroutine compute_sl_coefficients diff --git a/science/gungho/source/algorithm/transport/control/gungho_transport_control_alg_mod.X90 b/science/gungho/source/algorithm/transport/control/gungho_transport_control_alg_mod.X90 index 7ebe3d4eb..c9b1f6f50 100644 --- a/science/gungho/source/algorithm/transport/control/gungho_transport_control_alg_mod.X90 +++ b/science/gungho/source/algorithm/transport/control/gungho_transport_control_alg_mod.X90 @@ -34,6 +34,8 @@ module gungho_transport_control_alg_mod use check_configuration_mod, only: check_any_shifted, & check_transport_name, & check_any_eqn_consistent + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -209,8 +211,6 @@ contains coarse_collection_transport_alg use transport_field_mod, only: transport_field use wind_transport_alg_mod, only: wind_transport_alg - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer implicit none @@ -262,9 +262,9 @@ contains type(transport_metadata_type), pointer :: transport_metadata type(transport_controller_type) :: transport_controller type(transport_controller_type) :: aerosol_transport_controller + integer(tik) :: id_cont - if ( subroutine_timers ) call timer('gungho_transport_control') - + if ( LPROF ) call start_timing( id_cont, 'dynamics.transport' ) ! ======================================================================== ! ! Pre-transport initialisation tasks ! ======================================================================== ! @@ -380,13 +380,11 @@ contains mr_out, mr_in, nummr_to_transport, & transport_controller, transport_metadata & ) - ! ---------------------------------------------------------------------- ! ! Transport tracers which are active in fast physics, and therefore need ! transporting on every outer iteration if (present(adv_tracer_all_outer) & .and. check_transport_name('adv_tracer') ) then - call log_event( & "Transporting advective tracers (all)...", LOG_LEVEL_DEBUG & ) @@ -400,7 +398,6 @@ contains end if if (present(con_tracer_all_outer) & .and. check_transport_name('con_tracer') ) then - call log_event( & "Transporting conservative tracers (all)...", LOG_LEVEL_DEBUG & ) @@ -479,7 +476,6 @@ contains ! Advective tracers if (present(adv_tracer_last_outer) & .and. check_transport_name('adv_tracer') ) then - call log_event( & "Transporting advective tracers (last)...", LOG_LEVEL_DEBUG & ) @@ -498,7 +494,6 @@ contains ! Conservative tracers if (present(con_tracer_last_outer) & .and. check_transport_name('con_tracer') ) then - call log_event( & "Transporting conservative tracers (last)...", LOG_LEVEL_DEBUG & ) @@ -555,7 +550,7 @@ contains call transport_controller%finalise() call aerosol_transport_controller%finalise() - if ( subroutine_timers ) call timer('gungho_transport_control') + if ( LPROF ) call stop_timing( id_cont, 'dynamics.transport' ) end subroutine gungho_transport_control_alg diff --git a/science/gungho/source/algorithm/transport/control/moist_mr_transport_alg_mod.x90 b/science/gungho/source/algorithm/transport/control/moist_mr_transport_alg_mod.x90 index 98c9f75b3..34de02baf 100644 --- a/science/gungho/source/algorithm/transport/control/moist_mr_transport_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/control/moist_mr_transport_alg_mod.x90 @@ -9,10 +9,8 @@ module moist_mr_transport_alg_mod use constants_mod, only: i_def, r_def use field_mod, only: field_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_ERROR use mr_indices_mod, only: nummr - use timer_mod, only: timer use transport_enumerated_types_mod, only: equation_form_advective, & equation_form_conservative, & equation_form_consistent @@ -62,8 +60,6 @@ contains integer(kind=i_def) :: imr integer(kind=i_def) :: equation_form - if ( subroutine_timers ) call timer('transport.moisture') - ! If performing advective transport in the first outer loop, then the ! transport metadata needs setting here to make that choice ! The transport metadata will then be reset correctly within transport_field @@ -132,8 +128,6 @@ contains call invoke( setval_X(mr_out_rdef(imr), mr_in_rdef(imr)) ) end do - if ( subroutine_timers ) call timer('transport.moisture') - end subroutine moist_mr_transport_alg end module moist_mr_transport_alg_mod diff --git a/science/gungho/source/algorithm/transport/control/theta_transport_alg_mod.x90 b/science/gungho/source/algorithm/transport/control/theta_transport_alg_mod.x90 index 55c1c3b9a..ad31be337 100644 --- a/science/gungho/source/algorithm/transport/control/theta_transport_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/control/theta_transport_alg_mod.x90 @@ -24,7 +24,6 @@ module theta_transport_alg_mod use function_space_collection_mod, only: function_space_collection use fv_divergence_3d_kernel_mod, only: fv_divergence_3d_kernel_type use sci_geometric_constants_mod, only: get_height_fv, get_height_fe - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_ERROR use map_w2_to_sh_w2_alg_mod, only: map_w2_to_sh_w2_alg use mesh_mod, only: mesh_type @@ -42,7 +41,6 @@ module theta_transport_alg_mod get_num_split_steps, & get_dry_config use theta_moist_source_kernel_mod, only: theta_moist_source_kernel_type - use timer_mod, only: timer use timestepping_config_mod, only: time_method => method, & method_semi_implicit use transport_config_mod, only: theta_variable, & diff --git a/science/gungho/source/algorithm/transport/control/tracer_collection_transport_alg_mod.x90 b/science/gungho/source/algorithm/transport/control/tracer_collection_transport_alg_mod.x90 index e8d80ac54..421768138 100644 --- a/science/gungho/source/algorithm/transport/control/tracer_collection_transport_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/control/tracer_collection_transport_alg_mod.x90 @@ -16,14 +16,11 @@ module tracer_collection_transport_mod use field_collection_iterator_mod, only: field_collection_iterator_type use function_space_mod, only: function_space_type use function_space_collection_mod, only: function_space_collection - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_DEBUG use mesh_mod, only: mesh_type use mesh_collection_mod, only: mesh_collection - use timer_mod, only: timer - use transport_controller_mod, only: transport_controller_type use transport_enumerated_types_mod, only: equation_form_advective, & equation_form_conservative, & @@ -79,8 +76,6 @@ contains integer(kind=i_def) :: equation_form - if ( subroutine_timers ) call timer('transport.tracer_collection') - ! If performing advective transport in the first outer loop, then the ! transport metadata needs setting here to make that choice ! The transport metadata will then be reset correctly within transport_field @@ -162,8 +157,6 @@ contains ! but in case there are no fields in the collection, also reset it here call transport_controller%after_transport_field() - if ( subroutine_timers ) call timer('transport.tracer_collection') - end subroutine tracer_collection_transport_alg @@ -216,8 +209,6 @@ contains ! Transport runtime and form of transport equation integer(kind=i_def) :: equation_form - if ( subroutine_timers ) call timer('transport.tracer_collection') - ! If performing advective transport in the first outer loop, then the ! transport metadata needs setting here to make that choice call transport_controller%before_transport_field(transport_metadata) @@ -301,8 +292,6 @@ contains end if - if ( subroutine_timers ) call timer('transport.tracer_collection') - end subroutine coarse_collection_transport_alg end module tracer_collection_transport_mod diff --git a/science/gungho/source/algorithm/transport/control/transport_controller_mod.x90 b/science/gungho/source/algorithm/transport/control/transport_controller_mod.x90 index c6e678f8f..f5a29f696 100644 --- a/science/gungho/source/algorithm/transport/control/transport_controller_mod.x90 +++ b/science/gungho/source/algorithm/transport/control/transport_controller_mod.x90 @@ -35,7 +35,8 @@ module transport_controller_mod use mesh_collection_mod, only: mesh_collection use model_clock_mod, only: model_clock_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Pointers to other objects use sci_geometric_constants_mod, only: get_face_selector_ew, & @@ -61,7 +62,6 @@ module transport_controller_mod ! Config use departure_points_config_mod, only: share_stencil_extent - use io_config_mod, only: subroutine_timers use transport_config_mod, only: dep_pt_stencil_extent implicit none @@ -79,6 +79,7 @@ module transport_controller_mod integer(kind=i_def) :: outer logical(kind=l_def) :: cheap_update_step = .false. logical(kind=l_def) :: adaptive_splitting = .false. + logical(kind=l_def) :: make_tracers_advective = .false. integer(kind=i_def) :: reference_splitting = IMDI integer(kind=i_def) :: max_courant_num = 0 logical(kind=l_def) :: dep_stencil_extent_computed = .false. @@ -206,8 +207,9 @@ contains logical(kind=l_def) :: fixed_multiple_substeps logical(kind=l_def) :: logged_lipschitz character(len=str_def) :: splitting_name + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.controller_init') + if ( LPROF ) call start_timing( id, 'transport.controller_init' ) ! Set options, to be passed to objects initialised later if (present(outer)) then @@ -481,7 +483,7 @@ contains call log_event(log_scratch_space, LOG_LEVEL_INFO) end if - if ( subroutine_timers ) call timer('transport.controller_init') + if ( LPROF ) call stop_timing( id, 'transport.controller_init' ) end subroutine initialise @@ -504,6 +506,7 @@ contains self%outer_set = .false. self%cheap_update_step = .false. self%adaptive_splitting = .false. + self%make_tracers_advective = .false. self%reference_splitting = IMDI self%dep_stencil_extent_computed = .false. call self%counter%finalise() @@ -533,6 +536,7 @@ contains use transport_config_mod, only: ffsl_unity_3d, & adjust_vhv_wind, & + adjust_tracer_equation, & substep_transport, & substep_transport_two, & substep_transport_four, & @@ -659,15 +663,34 @@ contains LOG_LEVEL_WARNING & ) - call log_event( & - 'Watkins algorithm failed to keep all reference fields ' // & - 'positive for the transport of tracers. This makes it ' // & - 'impossible to find sensible departure distances. Most likely ' // & - 'the input transporting wind to the transport scheme has a ' // & - 'maximum Lipschitz number that exceeds 1 somewhere, so check ' // & - 'so check these values. Stopping model now to fail gracefully', & - LOG_LEVEL_ERROR & - ) + if (adjust_tracer_equation) then + ! Use advective form for tracer transport instead of consistent form + call log_event( & + 'Reference field for tracer transport is negative, so ' // & + 'making all tracers advective for this step. This will ' // & + 'make tracer transport non-conservative. ', LOG_LEVEL_INFO & + ) + self%make_tracers_advective = .true. + else + ! Fail gracefully + call log_event( & + 'The Watkins algorithm failed to keep all reference fields ' // & + 'positive for the transport of tracers. This makes it ' // & + 'impossible to find sensible departure distances for (Flux ' // & + 'Form) Semi-Lagrangian transport. Stopping now to fail ' // & + 'gracefully.' // NEW_LINE('A') // NEW_LINE('A') // & + 'This is a common way for the model to fail. Most likely ' // & + 'the transporting wind passed to the transport scheme has ' // & + 'some unphysical values, and the corresponding maximum ' // & + 'Lipschitz number exceeds 1 somewhere, so check these ' // & + 'values in the log above, which may also indicate the ' // & + 'geographical location of the issue.' // & + NEW_LINE('A') // NEW_LINE('A') // & + 'If this failure has occurred in the first timestep, it can ' // & + 'signify issues with the initial conditions or ancillaries.', & + LOG_LEVEL_ERROR & + ) + end if end if else @@ -701,7 +724,8 @@ contains ! Initialise counter if (self%outer_set) then call self%metadata%update_metadata( & - self%outer, self%adaptive_splitting, self%reference_splitting & + self%outer, self%adaptive_splitting, self%reference_splitting, & + self%make_tracers_Advective & ) call self%counter%initialise( & self%metadata, self%dt_substep, self%num_substeps, self%outer & diff --git a/science/gungho/source/algorithm/transport/control/wind_transport_alg_mod.x90 b/science/gungho/source/algorithm/transport/control/wind_transport_alg_mod.x90 index 73a649ade..312777004 100644 --- a/science/gungho/source/algorithm/transport/control/wind_transport_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/control/wind_transport_alg_mod.x90 @@ -26,7 +26,6 @@ module wind_transport_alg_mod use function_space_mod, only: function_space_type use function_space_collection_mod, only: function_space_collection use sci_geometric_constants_mod, only: get_coordinates, get_panel_id - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_TRACE @@ -35,7 +34,8 @@ module wind_transport_alg_mod get_project_zdot_to_w2 use mesh_mod, only: mesh_type use operator_mod, only: operator_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_config_mod, only: broken_w2_projection use transport_constants_mod, only: get_element_order_h_transport, & get_element_order_v_transport @@ -102,8 +102,7 @@ contains type(function_space_type), pointer :: w2_fs type(function_space_type), pointer :: w2b_fs logical(kind=l_def) :: optimised_conversion - - if ( subroutine_timers ) call timer('transport.wind') + integer(tik) :: id_to, id_from k_h = get_element_order_h_transport() k_v = get_element_order_v_transport() @@ -137,7 +136,7 @@ contains ! Split wind into components in W3 ! -------------------------------------------------------------------- ! - if ( subroutine_timers ) call timer('transport.wind_to_comps') + if ( LPROF ) call start_timing( id_to, 'transport.wind_to_comps' ) do dir = 1,3 call u_w3_n(dir)%initialise( w3_fs ) @@ -165,7 +164,7 @@ contains call log_field_minmax( LOG_LEVEL_TRACE, 'ydot', u_w3_n(2) ) call log_field_minmax( LOG_LEVEL_TRACE, 'zdot', u_w3_n(3) ) - if ( subroutine_timers ) call timer('transport.wind_to_comps') + if ( LPROF ) call stop_timing( id_to, 'transport.wind_to_comps' ) ! -------------------------------------------------------------------- ! ! Transport wind components in W3 @@ -182,7 +181,7 @@ contains ! Return from components to full wind field in W2 ! -------------------------------------------------------------------- ! - if ( subroutine_timers ) call timer('transport.wind_from_comps') + if ( LPROF ) call start_timing( id_from, 'transport.wind_from_comps' ) project_xdot_to_w2 => get_project_xdot_to_w2(mesh%get_id()) project_ydot_to_w2 => get_project_ydot_to_w2(mesh%get_id()) @@ -246,7 +245,7 @@ contains enforce_bc_kernel_type(rhs_u) ) end if - if ( subroutine_timers ) call timer('transport.wind_from_comps') + if ( LPROF ) call stop_timing( id_from, 'transport.wind_from_comps' ) ! ---------------------------------------------------------------------- ! ! Default form of transport equation @@ -262,8 +261,6 @@ contains end if ! si_momentum_equation - if ( subroutine_timers ) call timer('transport.wind') - end subroutine wind_transport_alg end module wind_transport_alg_mod diff --git a/science/gungho/source/algorithm/transport/ffsl/ffsl_3d_alg_mod.x90 b/science/gungho/source/algorithm/transport/ffsl/ffsl_3d_alg_mod.x90 index a028b1068..645f8822a 100644 --- a/science/gungho/source/algorithm/transport/ffsl/ffsl_3d_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/ffsl/ffsl_3d_alg_mod.x90 @@ -20,7 +20,8 @@ module ffsl_3d_alg_mod use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_constants_mod, only: get_element_order_h_transport, & get_element_order_v_transport @@ -41,7 +42,6 @@ module ffsl_3d_alg_mod use combine_w2_field_kernel_mod, only: combine_w2_field_kernel_type ! Configuration options - use io_config_mod, only: subroutine_timers use transport_config_mod, only: ffsl_inner_order, & ffsl_outer_order @@ -134,8 +134,9 @@ contains real(kind=r_tran) :: third_dt logical(kind=l_def) :: compute_adv_inc integer(kind=i_def) :: vertical_order + integer(tik) :: id - if ( subroutine_timers ) call timer(routine_name) + if ( LPROF ) call start_timing( id, 'ffsl_3d_transport_alg' ) ! Get pre-computed objects and set pointers -------------------------------- mesh => field_n%get_mesh() @@ -284,7 +285,7 @@ contains call log_event('FFSL_3D: equation not implemented', LOG_LEVEL_ERROR) end select - if ( subroutine_timers ) call timer(routine_name) + if ( LPROF ) call stop_timing( id, 'ffsl_3d_transport_alg' ) end subroutine ffsl_3d_splitting_alg diff --git a/science/gungho/source/algorithm/transport/ffsl/ffsl_hori_alg_mod.x90 b/science/gungho/source/algorithm/transport/ffsl/ffsl_hori_alg_mod.x90 index 7b8f88d2f..52b693976 100644 --- a/science/gungho/source/algorithm/transport/ffsl/ffsl_hori_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/ffsl/ffsl_hori_alg_mod.x90 @@ -22,7 +22,8 @@ module ffsl_hori_alg_mod use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Transport control use flux_precomputations_alg_mod, only: flux_precomputations_type @@ -163,8 +164,9 @@ contains ! Useful constants real(kind=r_tran) :: half_dt logical(kind=l_def) :: swift_splitting + integer(tik) :: id - if ( subroutine_timers ) call timer(routine_name) + if ( LPROF ) call start_timing( id, 'transport.ffsl_horizontal' ) ! Get pre-computed objects and set pointers -------------------------------- mesh => field_n%get_mesh() @@ -259,7 +261,7 @@ contains end if end if - if ( subroutine_timers ) call timer(routine_name) + if ( LPROF ) call stop_timing( id, 'transport.ffsl_horizontal' ) end subroutine ffsl_hori_splitting_alg @@ -429,14 +431,13 @@ contains remap_depth) else call field_big_halo%initialise( field_n%get_function_space(), & - halo_depth=get_required_stencil_depth() ) + halo_depth=mesh%get_halo_depth() ) call invoke( setval_x(field_big_halo, field_n) ) end if ! Copy required as PSyclone doesn't allow the same field to be ! used as two kernel arguments field_ptr_copy => field_big_halo - if ( subroutine_timers ) call timer('transport.ffsl_hori_sweeps') ! MASS FLUX COMPUTATION ==================================================== if (panel_edge_treatment == panel_edge_treatment_special_edges) then ! Special edge treatment ------------------------------------------------ @@ -488,29 +489,22 @@ contains min_val, ndep, dt ) ) end if - if ( subroutine_timers ) call timer('transport.ffsl_hori_sweeps') - ! fluxes may need unifying to guarantee a unique flux for each face -------- if ( panel_edge_treatment == panel_edge_treatment_extended_mesh ) then - if ( subroutine_timers ) call timer('transport.ffsl_flux_unify') w2b_fs => function_space_collection%get_fs(mesh, 0, 0, W2Hbroken) call flux_broken%initialise( w2b_fs ) call invoke( average_w2_to_w2b_kernel_type(flux_broken, flux), & ffsl_unify_flux_kernel_type(flux, flux_broken, & 1, panel_id, 1) ) - if ( subroutine_timers ) call timer('transport.ffsl_flux_unify') end if ! Compute updated advective fields ----------------------------------------- - if ( subroutine_timers ) call timer('transport.ffsl_hori_update') call invoke( fv_divergence_x_kernel_type(increment_x, flux, detj_at_w3), & fv_divergence_y_kernel_type(increment_y, flux, detj_at_w3) ) call ffsl_advective_increment(increment_x, field_n, dt, adv_one_x) call ffsl_advective_increment(increment_y, field_n, dt, adv_one_y) - if ( subroutine_timers ) call timer('transport.ffsl_hori_update') - end subroutine ffsl_hori_cosmic_inner_alg !> @brief The first horizontal sweeps for FFSL with Swift splitting @@ -722,7 +716,7 @@ contains remap_depth) else call field_big_halo%initialise( field_n%get_function_space(), & - halo_depth=get_required_stencil_depth() ) + halo_depth=mesh%get_halo_depth() ) call invoke( setval_x(field_big_halo, field_n) ) end if @@ -737,7 +731,6 @@ contains field_ptr_copy => field_big_halo - if ( subroutine_timers ) call timer('transport.ffsl_hori_sweeps') ! MASS FLUX COMPUTATION ==================================================== if (panel_edge_treatment == panel_edge_treatment_remapping) then ! Use remapped fields at panel edges ------------------------------------- @@ -810,21 +803,17 @@ contains end if - if ( subroutine_timers ) call timer('transport.ffsl_hori_sweeps') - ! fluxes may need unifying to guarantee a unique flux for each face -------- if ( panel_edge_treatment == panel_edge_treatment_extended_mesh ) then - if ( subroutine_timers ) call timer('transport.ffsl_flux_unify') w2b_fs => function_space_collection%get_fs(mesh, 0, 0, W2Hbroken) call flux_broken%initialise( w2b_fs ) call invoke( average_w2_to_w2b_kernel_type(flux_broken, flux), & ffsl_unify_flux_kernel_type(flux, flux_broken, & 1, panel_id, 1) ) - if ( subroutine_timers ) call timer('transport.ffsl_flux_unify') + end if ! Compute advected fields - if ( subroutine_timers ) call timer('transport.ffsl_hori_update') call invoke( fv_difference_x_kernel_type(increment_x, flux), & fv_difference_y_kernel_type(increment_y, flux) ) ! Obtain updated mixing ratio by dividing by updated density @@ -833,8 +822,6 @@ contains call swift_inner_update_tracer(field_y, field_n, dry_mass_y, & dry_mass_n, increment_y, step_dt) - if ( subroutine_timers ) call timer('transport.ffsl_hori_update') - end subroutine ffsl_hori_swift_inner_alg !> @brief Performs the outer horizontal steps of X and Y horizontal FFSL sweeps @@ -1088,8 +1075,8 @@ contains transport_metadata%get_min_value(), & remap_depth) else - call field_x_big_halo%initialise(field_fs, halo_depth=get_required_stencil_depth()) - call field_y_big_halo%initialise(field_fs, halo_depth=get_required_stencil_depth()) + call field_x_big_halo%initialise(field_fs, halo_depth=mesh%get_halo_depth()) + call field_y_big_halo%initialise(field_fs, halo_depth=mesh%get_halo_depth()) call invoke( setval_x(field_x_big_halo, field_x), & setval_x(field_y_big_halo, field_y) ) end if @@ -1104,8 +1091,6 @@ contains ) end if - if ( subroutine_timers ) call timer('transport.ffsl_hori_sweeps') - ! MASS FLUX COMPUTATION ==================================================== if (panel_edge_treatment == panel_edge_treatment_remapping) then ! Use remapped fields at panel edges ------------------------------------- @@ -1179,22 +1164,17 @@ contains end if - if ( subroutine_timers ) call timer('transport.ffsl_hori_sweeps') - ! fluxes may need unifying to guarantee a unique flux for each face -------- if ( panel_edge_treatment == panel_edge_treatment_extended_mesh ) then - if ( subroutine_timers ) call timer('transport.ffsl_flux_unify') w2b_fs => function_space_collection%get_fs(mesh, 0, 0, W2Hbroken) call flux_broken%initialise( w2b_fs ) call invoke( average_w2_to_w2b_kernel_type(flux_broken, flux), & ffsl_unify_flux_kernel_type(flux, flux_broken, & 1, panel_id, 1) ) - if ( subroutine_timers ) call timer('transport.ffsl_flux_unify') end if ! Compute advective increments, if required -------------------------------- if (to_compute_adv_inc .or. to_compute_field_np1) then - if ( subroutine_timers ) call timer('transport.ffsl_hori_update') call increment_x%initialise( vector_space = field_fs ) call increment_y%initialise( vector_space = field_fs ) @@ -1262,7 +1242,6 @@ contains end if end if - if ( subroutine_timers ) call timer('transport.ffsl_hori_update') end if end subroutine ffsl_hori_outer_alg diff --git a/science/gungho/source/algorithm/transport/ffsl/ffsl_vert_alg_mod.x90 b/science/gungho/source/algorithm/transport/ffsl/ffsl_vert_alg_mod.x90 index 23f70801b..eb972d3b5 100644 --- a/science/gungho/source/algorithm/transport/ffsl/ffsl_vert_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/ffsl/ffsl_vert_alg_mod.x90 @@ -18,7 +18,8 @@ module ffsl_vert_alg_mod use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Transport control use flux_precomputations_alg_mod, only: flux_precomputations_type @@ -49,7 +50,6 @@ module ffsl_vert_alg_mod use fv_divergence_z_kernel_mod, only: fv_divergence_z_kernel_type ! Configuration options - use io_config_mod, only: subroutine_timers use transport_config_mod, only: ffsl_unity_3d, & wind_mono_top, & wind_mono_top_depth @@ -131,8 +131,9 @@ contains ! Useful constants integer(kind=i_def) :: mesh_id, step real(kind=r_tran) :: one_over_dt + integer(tik) :: id - if ( subroutine_timers ) call timer(routine_name) + if ( LPROF ) call start_timing( id, 'transport.ffsl_vertical' ) transport_counter => transport_controller%get_transport_counter() transport_metadata => transport_controller%get_transport_metadata() @@ -206,8 +207,7 @@ contains step_dt, increment) ) end if end if - - if ( subroutine_timers ) call timer(routine_name) + if ( LPROF ) call stop_timing( id, 'transport.ffsl_vertical' ) end subroutine ffsl_vert_transport_alg diff --git a/science/gungho/source/algorithm/transport/mol/mol_advective_alg_mod.x90 b/science/gungho/source/algorithm/transport/mol/mol_advective_alg_mod.x90 index 4e9d1e563..16d16b65d 100644 --- a/science/gungho/source/algorithm/transport/mol/mol_advective_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/mol/mol_advective_alg_mod.x90 @@ -11,7 +11,8 @@ module mol_advective_alg_mod use constants_mod, only: r_def, i_def, l_def, r_tran use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Algorithms and transport code use advective_and_flux_alg_mod, only: advective_and_flux_alg @@ -27,7 +28,6 @@ module mol_advective_alg_mod ! Configuration use base_mesh_config_mod, only: topology, topology_non_periodic use boundaries_config_mod, only: limited_area, transport_boundary_depth - use io_config_mod, only: subroutine_timers use transport_config_mod, only: runge_kutta_method implicit none @@ -73,9 +73,10 @@ contains type(transport_counter_type), pointer :: transport_counter type(transport_metadata_type), pointer :: transport_metadata type(wind_precomputations_type), pointer :: wind_precomputations + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.mol_advective') + if ( LPROF ) call start_timing( id, 'transport.mol_advective' ) ! ------------------------------------------------------------------------ ! ! Extract pre-existing objects and initialise temporary fields @@ -177,7 +178,7 @@ contains if ( allocated( rk_field ) ) deallocate( rk_field ) if ( allocated( rk_weights ) ) deallocate( rk_weights ) - if ( subroutine_timers ) call timer('transport.mol_advective') + if ( LPROF ) call stop_timing( id, 'transport.mol_advective' ) end subroutine mol_advective_alg diff --git a/science/gungho/source/algorithm/transport/mol/mol_conservative_alg_mod.x90 b/science/gungho/source/algorithm/transport/mol/mol_conservative_alg_mod.x90 index cd0bfb1b8..9d8d4fc67 100644 --- a/science/gungho/source/algorithm/transport/mol/mol_conservative_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/mol/mol_conservative_alg_mod.x90 @@ -15,7 +15,8 @@ module mol_conservative_alg_mod use operator_mod, only: operator_type use r_tran_field_mod, only: r_tran_field_type use r_tran_operator_mod, only: r_tran_operator_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Algorithms and transport code use advective_and_flux_alg_mod, only: advective_and_flux_alg @@ -39,7 +40,6 @@ module mol_conservative_alg_mod ! Configuration use base_mesh_config_mod, only: topology, topology_non_periodic use boundaries_config_mod, only: limited_area, transport_boundary_depth - use io_config_mod, only: subroutine_timers use transport_config_mod, only: runge_kutta_method, & dry_field_name, & operators, & @@ -96,8 +96,9 @@ module mol_conservative_alg_mod type(transport_metadata_type), pointer :: transport_metadata type(wind_precomputations_type), pointer :: wind_precomputations type(flux_precomputations_type), pointer :: flux_precomputations + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.mol_conservative') + if ( LPROF ) call start_timing( id, 'transport.mol_conservective' ) ! ------------------------------------------------------------------------ ! ! Extract pre-existing objects and initialise temporary fields @@ -273,7 +274,7 @@ module mol_conservative_alg_mod if ( allocated(rk_field) ) deallocate(rk_field) if ( allocated(rk_weights) ) deallocate(rk_weights) - if ( subroutine_timers ) call timer('transport.mol_conservative') + if ( LPROF ) call stop_timing( id, 'transport.mol_conservective' ) end subroutine mol_conservative_alg diff --git a/science/gungho/source/algorithm/transport/mol/mol_consistent_alg_mod.x90 b/science/gungho/source/algorithm/transport/mol/mol_consistent_alg_mod.x90 index e64af7764..bbdf8e6ab 100644 --- a/science/gungho/source/algorithm/transport/mol/mol_consistent_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/mol/mol_consistent_alg_mod.x90 @@ -18,7 +18,8 @@ module mol_consistent_alg_mod use mesh_mod, only: mesh_type use mesh_collection_mod, only: mesh_collection use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Algorithms and transport code use advective_and_flux_alg_mod, only: advective_and_flux_alg @@ -41,7 +42,6 @@ module mol_consistent_alg_mod use base_mesh_config_mod, only: topology, topology_non_periodic use boundaries_config_mod, only: limited_area, & transport_boundary_depth - use io_config_mod, only: subroutine_timers use transport_config_mod, only: runge_kutta_method implicit none @@ -104,8 +104,9 @@ module mol_consistent_alg_mod type(transport_metadata_type), pointer :: transport_metadata type(wind_precomputations_type), pointer :: wind_precomputations type(flux_precomputations_type), pointer :: flux_precomputations + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.mol_consistent') + if ( LPROF ) call start_timing( id, 'transport.mol_consistent' ) ! ------------------------------------------------------------------------ ! ! Extract pre-existing objects and initialise temporary fields @@ -335,7 +336,7 @@ module mol_consistent_alg_mod if ( allocated( rk_field ) ) deallocate( rk_field ) if ( allocated( rk_weights ) ) deallocate( rk_weights ) - if ( subroutine_timers ) call timer('transport.mol_consistent') + if ( LPROF ) call stop_timing( id, 'transport.mol_consistent' ) end subroutine mol_consistent_alg diff --git a/science/gungho/source/algorithm/transport/mol/reconstruct_w3_field_alg_mod.x90 b/science/gungho/source/algorithm/transport/mol/reconstruct_w3_field_alg_mod.x90 index 6bed73bed..6b9b9e537 100644 --- a/science/gungho/source/algorithm/transport/mol/reconstruct_w3_field_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/mol/reconstruct_w3_field_alg_mod.x90 @@ -18,7 +18,6 @@ !! size as an integer argument. module reconstruct_w3_field_alg_mod - use check_configuration_mod, only: get_required_stencil_depth use sci_combine_multidata_field_kernel_mod, & only: combine_multidata_field_kernel_type use constants_mod, only: r_def, i_def, l_def, str_def @@ -60,8 +59,8 @@ module reconstruct_w3_field_alg_mod use polyv_w3_koren_kernel_mod, only: polyv_w3_koren_kernel_type use polyh_w3_koren_kernel_mod, only: polyh_w3_koren_kernel_type - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -176,8 +175,9 @@ contains integer(kind=i_def) :: stencil_size logical(kind=l_def) :: monotone integer(kind=i_def) :: remap_depth + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.w3_hori_recon') + if ( LPROF ) call start_timing( id, 'mol.w3_hori_recon' ) mesh => field_new%get_mesh() mesh_id = mesh%get_id() @@ -196,7 +196,7 @@ contains ! Copy field to a large halo version call field_old_big_halo%initialise( field_old%get_function_space(), & - halo_depth = get_required_stencil_depth() ) + halo_depth=mesh%get_halo_depth() ) call invoke( setval_X( field_old_big_halo, field_old ) ) monotone = (transport_metadata%get_horizontal_monotone() == monotone_koren) @@ -237,7 +237,7 @@ contains stencil_size) ) end if - if ( subroutine_timers ) call timer('transport.w3_hori_recon') + if ( LPROF ) call stop_timing( id, 'mol.w3_hori_recon' ) end subroutine hori_w3_reconstruct_alg @@ -268,8 +268,9 @@ contains logical(kind=l_def) :: logspace logical(kind=l_def) :: reversible integer(kind=i_def) :: monotonicity + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.w3_vert_recon') + if ( LPROF ) call start_timing( id, 'mol.w3_vert_recon' ) reversible = ( transport_metadata%get_reversible() .and. final_rk_stage ) logspace = transport_metadata%get_log_space() @@ -311,7 +312,7 @@ contains end if - if ( subroutine_timers ) call timer('transport.w3_vert_recon') + if ( LPROF ) call stop_timing( id, 'mol.w3_vert_recon' ) end subroutine vert_w3_reconstruct_alg diff --git a/science/gungho/source/algorithm/transport/mol/wt_advective_update_alg_mod.x90 b/science/gungho/source/algorithm/transport/mol/wt_advective_update_alg_mod.x90 index 310165201..46b6b5fbc 100644 --- a/science/gungho/source/algorithm/transport/mol/wt_advective_update_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/mol/wt_advective_update_alg_mod.x90 @@ -18,7 +18,6 @@ !! size as an integer argument. module wt_advective_update_alg_mod - use check_configuration_mod, only: get_required_stencil_depth use constants_mod, only: r_def, i_def, l_def, str_def, & r_tran use sci_geometric_constants_mod, only: get_coordinates, & @@ -67,8 +66,8 @@ module wt_advective_update_alg_mod use polyh_wtheta_koren_kernel_mod, only: polyh_wtheta_koren_kernel_type use polyv_wtheta_koren_kernel_mod, only: polyv_wtheta_koren_kernel_type use copy_field_alg_mod, only: copy_field - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -113,8 +112,9 @@ contains integer(kind=i_def) :: stencil_size logical(kind=l_def) :: monotone integer(kind=i_def) :: remap_depth + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.wt_hori_recon') + if ( LPROF ) call start_timing( id, 'mol.wt_hori_recon' ) mesh => wind%get_mesh() mesh_id = mesh%get_id() @@ -132,7 +132,7 @@ contains ! Copy field to a large halo version call field_big_halo%initialise( field%get_function_space(), & - halo_depth = get_required_stencil_depth() ) + halo_depth=mesh%get_halo_depth() ) call invoke( setval_X( field_big_halo, field ) ) ! Compute reconstruction on a Wtheta multidata field @@ -196,7 +196,7 @@ contains wind, & wind_dir, stencil_extent)) - if ( subroutine_timers ) call timer('transport.wt_hori_recon') + if ( LPROF ) call stop_timing( id, 'mol.wt_hori_recon' ) end subroutine hori_wt_update_alg @@ -230,8 +230,9 @@ contains logical(kind=l_def) :: logspace logical(kind=l_def) :: reversible integer(kind=i_def) :: monotonicity + integer(tik) :: id - if ( subroutine_timers ) call timer('transport.wt_vert_recon') + if ( LPROF ) call start_timing( id, 'mol.wt_vert_recon' ) reversible = ( transport_metadata%get_reversible() .and. final_rk_stage ) logspace = transport_metadata%get_log_space() @@ -268,7 +269,7 @@ contains logspace ) ) end if - if ( subroutine_timers ) call timer('transport.wt_vert_recon') + if ( LPROF ) call stop_timing( id, 'mol.wt_vert_recon' ) end subroutine vert_wt_update_alg diff --git a/science/gungho/source/algorithm/transport/sl/horizontal_sl_advective_alg_mod.x90 b/science/gungho/source/algorithm/transport/sl/horizontal_sl_advective_alg_mod.x90 index d547900e1..3b09e0618 100644 --- a/science/gungho/source/algorithm/transport/sl/horizontal_sl_advective_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/sl/horizontal_sl_advective_alg_mod.x90 @@ -18,7 +18,8 @@ module horizontal_sl_advective_alg_mod use integer_field_mod, only: integer_field_type use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Transport control use flux_precomputations_alg_mod, only: flux_precomputations_type @@ -53,7 +54,6 @@ module horizontal_sl_advective_alg_mod transport_overwrite_freq, & transport_overwrite_freq_all use departure_points_config_mod, only: share_stencil_extent - use io_config_mod, only: subroutine_timers use transport_config_mod, only: & panel_edge_treatment, & panel_edge_treatment_extended_mesh, & @@ -119,6 +119,8 @@ module horizontal_sl_advective_alg_mod logical(kind=l_def) :: do_overwrite real(kind=r_tran) :: dt_frac, dt real(kind=r_tran) :: one_over_dt, half_dt + integer(tik) :: id + ! Transport objects type(wind_precomputations_type), pointer :: wind_precomputations @@ -128,7 +130,7 @@ module horizontal_sl_advective_alg_mod type(r_tran_field_type), pointer :: dep_dist_xy integer(kind=i_def) :: dep_stencil_extent_xy - if ( subroutine_timers ) call timer('transport.sl_horizontal') + if ( LPROF ) call start_timing( id, 'transport.sl_horizontal' ) ! Get mesh ID and panel ID mesh_id = field_n%get_mesh_id() @@ -295,7 +297,7 @@ module horizontal_sl_advective_alg_mod field_np1, field_n, transport_counter, transport_metadata & ) - if ( subroutine_timers ) call timer('transport.sl_horizontal') + if ( LPROF ) call stop_timing( id, 'transport.sl_horizontal' ) end subroutine horizontal_sl_advective_alg diff --git a/science/gungho/source/algorithm/transport/sl/vertical_sl_advective_alg_mod.x90 b/science/gungho/source/algorithm/transport/sl/vertical_sl_advective_alg_mod.x90 index 0828d532a..46e7b4698 100644 --- a/science/gungho/source/algorithm/transport/sl/vertical_sl_advective_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/sl/vertical_sl_advective_alg_mod.x90 @@ -17,7 +17,8 @@ module vertical_sl_advective_alg_mod use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use r_tran_field_mod, only: r_tran_field_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Transport control use transport_controller_mod, only: transport_controller_type @@ -37,7 +38,6 @@ module vertical_sl_advective_alg_mod use vertical_quintic_sl_kernel_mod, only: vertical_quintic_sl_kernel_type ! Configs - use io_config_mod, only: subroutine_timers use transport_config_mod, only: vertical_sl_order, & vertical_sl_order_cubic, & vertical_sl_order_quintic, & @@ -84,13 +84,14 @@ contains integer(kind=i_def) :: splitting logical(kind=l_def) :: reversibility logical(kind=l_def) :: log_space + integer(tik) :: id ! Interpolation coefficients type(r_tran_field_type), pointer :: linear_coeffs(:) type(r_tran_field_type), pointer :: interp_coeffs(:) type(integer_field_type), pointer :: interp_indices(:) - if ( subroutine_timers ) call timer( 'transport.sl_vertical' ) + if ( LPROF ) call start_timing( id, 'transport.sl_vertical' ) if ( vertical_sl_order /= vertical_sl_order_cubic .and. & vertical_sl_order /= vertical_sl_order_cubic_hermite .and. & @@ -187,7 +188,7 @@ contains field_np1, field_n, transport_counter, transport_metadata & ) - if ( subroutine_timers ) call timer( 'transport.sl_vertical' ) + if ( LPROF ) call stop_timing( id, 'transport.sl_vertical' ) end subroutine vertical_sl_advective_alg diff --git a/science/gungho/source/algorithm/transport/sl/vertical_sl_conservative_alg_mod.x90 b/science/gungho/source/algorithm/transport/sl/vertical_sl_conservative_alg_mod.x90 index 77ec2cd1b..8c5741982 100644 --- a/science/gungho/source/algorithm/transport/sl/vertical_sl_conservative_alg_mod.x90 +++ b/science/gungho/source/algorithm/transport/sl/vertical_sl_conservative_alg_mod.x90 @@ -21,7 +21,8 @@ module vertical_sl_conservative_alg_mod use r_tran_field_mod, only: r_tran_field_type use r_tran_operator_mod, only: r_tran_operator_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Transport control use flux_precomputations_alg_mod, only: flux_precomputations_type @@ -51,7 +52,6 @@ module vertical_sl_conservative_alg_mod get_inverse_mass_matrix_r_tran ! Configs - use io_config_mod, only: subroutine_timers use transport_config_mod, only: slice_order, & slice_order_linear, & slice_order_parabola, & @@ -117,8 +117,9 @@ contains logical(kind=l_def) :: reversibility logical(kind=l_def) :: enforce_min_value logical(kind=l_def) :: final_split_step + integer(tik) :: id - if ( subroutine_timers ) call timer( 'transport.slice_vertical' ) + if ( LPROF ) call start_timing( id, 'transport.slice_vertical' ) if ( slice_order /= slice_order_linear .and. & slice_order /= slice_order_cubic .and. & @@ -247,7 +248,7 @@ contains transport_counter, transport_metadata & ) - if ( subroutine_timers ) call timer( 'transport.slice_vertical' ) + if ( LPROF ) call stop_timing( id, 'transport.slice_vertical' ) end subroutine vertical_sl_conservative_alg diff --git a/science/gungho/source/configuration/check_configuration_mod.F90 b/science/gungho/source/configuration/check_configuration_mod.F90 index 86252a85a..e2a1e8e6e 100644 --- a/science/gungho/source/configuration/check_configuration_mod.F90 +++ b/science/gungho/source/configuration/check_configuration_mod.F90 @@ -6,7 +6,7 @@ module check_configuration_mod - use constants_mod, only: i_def, l_def + use constants_mod, only: i_def, l_def, str_def use mixing_config_mod, only: viscosity, & viscosity_mu use transport_config_mod, only: operators, & @@ -48,7 +48,7 @@ module check_configuration_mod substep_transport, & substep_transport_off, & adjust_vhv_wind, & - ffsl_unity_3d, & + ffsl_unity_3d, & wind_mono_top use transport_enumerated_types_mod, & only: scheme_mol_3d, & @@ -71,6 +71,9 @@ module check_configuration_mod monotone_qm_pos, & ffsl_splitting_swift, & ffsl_splitting_cosmic + use namelist_collection_mod, & + only : namelist_collection_type + use namelist_mod, only : namelist_type implicit none @@ -612,31 +615,87 @@ subroutine check_configuration(modeldb) end subroutine check_configuration - !> @brief Determine required stencil depth for the current configuration. + !> @brief Determine required stencil depth for the current configuration, + !! for each mesh. !> @details Depending on the choice of science schemes the required local !> mesh needs to support the anticipated stencils. This function !> returns required stencil depth that needs to be supported. - !> @return stencil_depth - !> + !> @param[in,out] stencil_depths Array of stencil depths for each base mesh + !> @param[in] base_mesh_names Array of base mesh names + !> @param[in] configuration The configuration object !=========================================================================== - function get_required_stencil_depth() result(stencil_depth) + subroutine get_required_stencil_depth(stencil_depths, base_mesh_names, configuration) implicit none - integer(kind=i_def) :: stencil_depth - integer(kind=i_def) :: sl_depth, special_edge_pts + integer(kind=i_def), intent(inout) :: stencil_depths(:) + character(len=str_def), intent(in) :: base_mesh_names(:) + type(namelist_collection_type), intent(in) :: configuration + + + integer(kind=i_def) :: i + integer(kind=i_def) :: transport_depth, sl_depth + integer(kind=i_def) :: special_edge_pts logical(kind=l_def) :: any_horz_dep_pts - stencil_depth = 2 + ! Configuration variables + type(namelist_type), pointer :: base_mesh_nml + type(namelist_type), pointer :: formulation_nml + type(namelist_type), pointer :: multires_coupling_nml + type(namelist_type), pointer :: transport_nml + character(len=str_def) :: prime_mesh_name + character(len=str_def) :: aerosol_mesh_name + logical(kind=l_def) :: use_multires_coupling + logical(kind=l_def) :: coarse_aerosol_transport + integer(kind=i_def) :: operators + integer(kind=i_def) :: fv_horizontal_order + integer(kind=i_def) :: panel_edge_treatment + logical(kind=l_def) :: panel_edge_high_order + integer(kind=i_def) :: dep_pt_stencil_extent + integer(kind=i_def) :: ffsl_inner_order + integer(kind=i_def) :: ffsl_outer_order + + ! ------------------------------------------------------------------------ ! + ! Get configuration variables + ! ------------------------------------------------------------------------ ! + + base_mesh_nml => configuration%get_namelist('base_mesh') + formulation_nml => configuration%get_namelist('formulation') + transport_nml => configuration%get_namelist('transport') + + call base_mesh_nml%get_value('prime_mesh_name', prime_mesh_name) + call formulation_nml%get_value('use_multires_coupling', use_multires_coupling) + call transport_nml%get_value('operators', operators) + call transport_nml%get_value('fv_horizontal_order', fv_horizontal_order) + call transport_nml%get_value('panel_edge_treatment', panel_edge_treatment) + call transport_nml%get_value('panel_edge_high_order', panel_edge_high_order) + call transport_nml%get_value('dep_pt_stencil_extent', dep_pt_stencil_extent) + call transport_nml%get_value('ffsl_inner_order', ffsl_inner_order) + call transport_nml%get_value('ffsl_outer_order', ffsl_outer_order) + if (use_multires_coupling) then + multires_coupling_nml => configuration%get_namelist('multires_coupling') + call multires_coupling_nml%get_value('aerosol_mesh_name', aerosol_mesh_name) + call multires_coupling_nml%get_value('coarse_aerosol_transport', coarse_aerosol_transport) + end if + + ! ------------------------------------------------------------------------ ! + ! Set default depth + ! ------------------------------------------------------------------------ ! + + transport_depth = 2 if (operators == operators_fv) then ! Need larger halos for fv operators - stencil_depth = max( stencil_depth, fv_horizontal_order/2 ) + transport_depth = max( transport_depth, fv_horizontal_order/2 ) end if + ! ------------------------------------------------------------------------ ! + ! Determine depth when using a semi-Lagrangian scheme + ! ------------------------------------------------------------------------ ! + any_horz_dep_pts = check_horz_dep_pts() - if ( any_horz_dep_pts ) then + if (any_horz_dep_pts) then ! When an SL scheme is used, the halo depth should be large enough to ! encompass the largest anticipated Courant number (effectively the ! departure distance in the SL scheme), plus any extra cells required for @@ -646,8 +705,8 @@ function get_required_stencil_depth() result(stencil_depth) ! - the order of reconstruction ! - whether special edge treatment is used (this shifts the stencil by 1) - if ( panel_edge_treatment == panel_edge_treatment_special_edges & - .AND. panel_edge_high_order ) then + if (panel_edge_treatment == panel_edge_treatment_special_edges & + .AND. panel_edge_high_order) then special_edge_pts = 1 else special_edge_pts = 0 @@ -659,18 +718,39 @@ function get_required_stencil_depth() result(stencil_depth) + special_edge_pts & ! special edge treatment ) - if ( panel_edge_treatment == panel_edge_treatment_remapping ) then - if ( panel_edge_high_order ) then - sl_depth = max( sl_depth, 3 ) + if (panel_edge_treatment == panel_edge_treatment_remapping) then + if (panel_edge_high_order) then + transport_depth = max( sl_depth, 3 ) else sl_depth = max( sl_depth, 2 ) end if end if - stencil_depth = max( stencil_depth, sl_depth ) + transport_depth = max( transport_depth, sl_depth ) end if - end function get_required_stencil_depth + ! ------------------------------------------------------------------------ ! + ! Set depth for each mesh + ! ------------------------------------------------------------------------ ! + + ! Loop through meshes to determine whether transport takes place on it + do i = 1, size(base_mesh_names) + if (trim(base_mesh_names(i)) == trim(prime_mesh_name)) then + ! Assume transport always occurs on prime mesh + stencil_depths(i) = transport_depth + + else if (use_multires_coupling .and. coarse_aerosol_transport .and. & + trim(base_mesh_names(i)) == trim(aerosol_mesh_name)) then + ! Coarse mesh transport for aerosols + stencil_depths(i) = transport_depth + + else + ! No transport on this mesh, so set stencil depth to 2 + stencil_depths(i) = 2 + end if + end do + + end subroutine get_required_stencil_depth !> @brief Determine whether any of the transport schemes are MoL !> @details Loops through the transport schemes specified for different diff --git a/science/gungho/source/diagnostics/diagnostics_io_mod.x90 b/science/gungho/source/diagnostics/diagnostics_io_mod.x90 index ad2f7737a..2b3c5dcec 100755 --- a/science/gungho/source/diagnostics/diagnostics_io_mod.x90 +++ b/science/gungho/source/diagnostics/diagnostics_io_mod.x90 @@ -17,6 +17,7 @@ module diagnostics_io_mod scalar_nodal_diagnostic_alg, & scalar_ugrid_diagnostic_alg, & vector_nodal_diagnostic_alg + use initialise_diagnostics_mod, only: diagnostic_to_be_sampled use io_config_mod, only: use_xios_io, write_fluxes use files_config_mod, only: diag_stem_name use function_space_collection_mod, only: function_space_collection @@ -139,9 +140,13 @@ subroutine write_scalar_diagnostic( field_name, field, & ! Check if we need to write an initial field if (clock%is_initialisation()) then - call output_field(1)%write_field(trim('init_'//field_name)) + if (diagnostic_to_be_sampled(trim('init_'//field_name))) then + call output_field(1)%write_field(trim('init_'//field_name)) + end if else - call output_field(1)%write_field(trim(field_name)) + if (diagnostic_to_be_sampled(trim(field_name))) then + call output_field(1)%write_field(trim(field_name)) + end if end if nullify(tmp_write_ptr) @@ -308,23 +313,47 @@ subroutine write_vector_diagnostic( field_name, field, & if (clock%is_initialisation()) then if (field_name == 'u') then - call u1_wind%write_field("init_u_in_w2h") - call u2_wind%write_field("init_v_in_w2h") - call u3_wind%write_field("init_w_in_wth") + if (diagnostic_to_be_sampled("init_u_in_w2h")) then + call u1_wind%write_field("init_u_in_w2h") + end if + if (diagnostic_to_be_sampled("init_v_in_w2h")) then + call u2_wind%write_field("init_v_in_w2h") + end if + if (diagnostic_to_be_sampled("init_w_in_wth")) then + call u3_wind%write_field("init_w_in_wth") + end if else - call u1_wind%write_field("init_"//trim(field_name)//"1") - call u2_wind%write_field("init_"//trim(field_name)//"2") - call u3_wind%write_field("init_"//trim(field_name)//"3") + if (diagnostic_to_be_sampled(trim(field_name)//"1")) then + call u1_wind%write_field("init_"//trim(field_name)//"1") + end if + if (diagnostic_to_be_sampled(trim(field_name)//"2")) then + call u2_wind%write_field("init_"//trim(field_name)//"2") + end if + if (diagnostic_to_be_sampled(trim(field_name)//"3")) then + call u3_wind%write_field("init_"//trim(field_name)//"3") + end if end if else if (field_name == 'u') then - call u1_wind%write_field("u_in_w2h") - call u2_wind%write_field("v_in_w2h") - call u3_wind%write_field("w_in_wth") + if (diagnostic_to_be_sampled("u_in_w2h")) then + call u1_wind%write_field("u_in_w2h") + end if + if (diagnostic_to_be_sampled("v_in_w2h")) then + call u2_wind%write_field("v_in_w2h") + end if + if (diagnostic_to_be_sampled("w_in_wth")) then + call u3_wind%write_field("w_in_wth") + end if else - call u1_wind%write_field(trim(field_name)//"1") - call u2_wind%write_field(trim(field_name)//"2") - call u3_wind%write_field(trim(field_name)//"3") + if (diagnostic_to_be_sampled(trim(field_name)//"1")) then + call u1_wind%write_field(trim(field_name)//"1") + end if + if (diagnostic_to_be_sampled(trim(field_name)//"2")) then + call u2_wind%write_field(trim(field_name)//"2") + end if + if (diagnostic_to_be_sampled(trim(field_name)//"3")) then + call u3_wind%write_field(trim(field_name)//"3") + end if end if end if diff --git a/science/gungho/source/diagnostics/external_forcing_diagnostics.f90 b/science/gungho/source/diagnostics/external_forcing_diagnostics.f90 index 7f0bc7751..021c9b01e 100644 --- a/science/gungho/source/diagnostics/external_forcing_diagnostics.f90 +++ b/science/gungho/source/diagnostics/external_forcing_diagnostics.f90 @@ -12,8 +12,7 @@ module external_forcing_diagnostics_mod use field_mod, only: field_type use log_mod, only: log_event, LOG_LEVEL_INFO use constants_mod, only: l_def - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF use initialise_diagnostics_mod, only: init_diag => init_diagnostic_field use physics_mappings_alg_mod, only: map_physics_winds @@ -40,8 +39,9 @@ subroutine write_forcing_diagnostics(du_forcing, output_wind_inc) output_dv_force, & output_dw_force type( field_type ) :: du_force, dv_force, dw_force + integer(tik) :: id - if ( subroutine_timers ) call timer("write_forcing_diagnostics") + if ( LPROF ) call start_timing( id, 'diags.external_forcing' ) if ( output_wind_inc ) then ! @@ -92,7 +92,7 @@ subroutine write_forcing_diagnostics(du_forcing, output_wind_inc) end if - if ( subroutine_timers ) call timer("write_forcing_diagnostics") + if ( LPROF ) call stop_timing( id, 'diags.external_forcing' ) end subroutine write_forcing_diagnostics diff --git a/science/gungho/source/driver/create_physics_prognostics_mod.F90 b/science/gungho/source/driver/create_physics_prognostics_mod.F90 index 649d501bd..a7f803c43 100644 --- a/science/gungho/source/driver/create_physics_prognostics_mod.F90 +++ b/science/gungho/source/driver/create_physics_prognostics_mod.F90 @@ -42,6 +42,7 @@ module create_physics_prognostics_mod topography_horizon, & n_horiz_layer, n_horiz_ang, & l_inc_radstep + use cosp_config_mod, only : l_cosp, n_cosp_step use aerosol_config_mod, only : glomap_mode, & glomap_mode_climatology, & glomap_mode_dust_and_clim, & @@ -471,6 +472,38 @@ subroutine process_physics_prognostics(processor) call processor%apply(make_spec('aer_lw_asymmetry', main%radiation, & ckp=checkpoint_flag)) + ! Fields which need checkpointing for time sampling of COSP diagnostics. + ! Checkpoint unless both the first timestep of this run and the + ! first timestep of the next run are COSP timesteps + if (l_cosp) then + checkpoint_flag = & + mod(clock%get_first_step()-1, n_cosp_step) /= 0 .or. & + mod(clock%get_last_step(), n_cosp_step) /= 0 + + if (checkpoint_read .or. init_option == init_option_checkpoint_dump) then + ! If the first timestep of this run IS a COSP timestep, but the + ! first timestep of the next run IS NOT, then checkpoint_flag + ! must be false to allow model to start running, as the COSP + ! prognostics will not be in the initial dump + if (mod(clock%get_first_step()-1, n_cosp_step) == 0 .and. & + mod(clock%get_last_step(), n_cosp_step) /= 0) then + checkpoint_flag = .false. + if (checkpoint_write) then + call log_event('Danger: start of this run is a COSP ' // & + 'timestep, but start of next run is not. ' // & + 'Written dump will be incomplete. Next run ' // & + 'must start with a COSP timestep', & + LOG_LEVEL_WARNING) + end if + endif + end if + else + checkpoint_flag = .false. + end if + + call processor%apply(make_spec('lit_fraction_cosp', main%radiation, & + W3, twod=.true., ckp=checkpoint_flag)) + !======================================================================== ! Fields owned by the microphysics scheme !======================================================================== @@ -1489,7 +1522,7 @@ subroutine process_physics_prognostics(processor) ! Fields owned by the aerosol scheme !======================================================================== - ! 2D fields, might need checkpointing + ! Flags for some 2D and 3D fields if ( aerosol == aerosol_um .and. glomap_mode == glomap_mode_ukca ) then checkpoint_flag = .true. checkpoint_GC3 = (emissions == emissions_GC3) @@ -1501,6 +1534,7 @@ subroutine process_physics_prognostics(processor) checkpoint_GC5 = .false. is_empty = .true. end if + ! 2D fields, might need checkpointing if ( aerosol == aerosol_um .and. & ( glomap_mode == glomap_mode_ukca .or. & glomap_mode == glomap_mode_dust_and_clim ) ) then @@ -1533,15 +1567,11 @@ subroutine process_physics_prognostics(processor) call processor%apply(make_spec('surf_wetness', main%aerosol, & empty=is_empty, ckp=checkpoint_flag)) end if - call processor%apply(make_spec('soil_clay', main%aerosol, & - ckp=checkpoint_flag)) - call processor%apply(make_spec('soil_sand', main%aerosol, & - ckp=checkpoint_flag)) + ! 3D fields, might need checkpointing - flags set above if ( aerosol == aerosol_um .and. & ( glomap_mode == glomap_mode_ukca .or. & glomap_mode == glomap_mode_dust_and_clim ) ) then - ! 3D fields, might need checkpointing call processor%apply(make_spec('emiss_bc_biomass', main%aerosol, & empty=is_empty, ckp=checkpoint_GC3)) call processor%apply(make_spec('emiss_om_biomass', main%aerosol, & @@ -1550,6 +1580,19 @@ subroutine process_physics_prognostics(processor) empty=is_empty, ckp=checkpoint_flag)) end if + ! Flags for more 2D fields + if (aerosol == aerosol_um .and. (glomap_mode == glomap_mode_ukca .or. & + glomap_mode == glomap_mode_dust_and_clim )) then + checkpoint_flag = .true. + else + checkpoint_flag = .false. + end if + + call processor%apply(make_spec('soil_clay', main%aerosol, & + ckp=checkpoint_flag)) + call processor%apply(make_spec('soil_sand', main%aerosol, & + ckp=checkpoint_flag)) + ! 3D fields, might need checkpointing and/or advecting ! Nucleation mode is only used with UKCA if ( aerosol == aerosol_um .and. glomap_mode == glomap_mode_ukca ) then @@ -1776,8 +1819,13 @@ subroutine process_physics_prognostics(processor) end if ! Fields on dust space, might need checkpointing - ! vector_space => function_space_collection%get_fs(twod_mesh, 0, 0, W3, - ! get_ndata_val('dust_divisions')) + if (aerosol == aerosol_um .and. (glomap_mode == glomap_mode_ukca .or. & + glomap_mode == glomap_mode_dust_and_clim )) then + checkpoint_flag = .true. + else + checkpoint_flag = .false. + end if + call processor%apply(make_spec('dust_mrel', main%aerosol, & ckp=checkpoint_flag)) diff --git a/science/gungho/source/driver/gungho_diagnostics_driver_mod.F90 b/science/gungho/source/driver/gungho_diagnostics_driver_mod.F90 index 12cc745a4..1bfca57a2 100644 --- a/science/gungho/source/driver/gungho_diagnostics_driver_mod.F90 +++ b/science/gungho/source/driver/gungho_diagnostics_driver_mod.F90 @@ -14,14 +14,14 @@ module gungho_diagnostics_driver_mod use constants_mod, only : i_def, r_def, str_def use boundaries_config_mod, only : limited_area, output_lbcs - use diagnostic_alg_mod, only : column_total_diagnostics_alg, & - calc_wbig_diagnostic_alg, & + use diagnostic_alg_mod, only : column_total_diagnostics_alg, & + calc_wbig_diagnostic_alg, & pressure_diag_alg - use diagnostics_io_mod, only : write_scalar_diagnostic, & + use diagnostics_io_mod, only : write_scalar_diagnostic, & write_vector_diagnostic - use diagnostics_calc_mod, only : write_divergence_diagnostic, & - write_hydbal_diagnostic, & - write_vorticity_diagnostic, & + use diagnostics_calc_mod, only : write_divergence_diagnostic, & + write_hydbal_diagnostic, & + write_vorticity_diagnostic, & write_pv_diagnostic use initialise_diagnostics_mod, only : diagnostic_to_be_sampled use field_array_mod, only : field_array_type @@ -32,24 +32,25 @@ module gungho_diagnostics_driver_mod use field_parent_mod, only : field_parent_type, write_interface use io_value_mod, only : io_value_type, get_io_value use lfric_xios_write_mod, only : write_field_generic - use formulation_config_mod, only : use_physics, & - moisture_formulation, & + use formulation_config_mod, only : use_physics, & + moisture_formulation, & moisture_formulation_dry - use fs_continuity_mod, only : W3, Wtheta + use fs_continuity_mod, only : W3, Wtheta, W2H, W0 use integer_field_mod, only : integer_field_type - use initialization_config_mod, only : ls_option, & - ls_option_analytic, & + use initialization_config_mod, only : ls_option, & + ls_option_analytic, & ls_option_file use mesh_mod, only : mesh_type use moist_dyn_mod, only : num_moist_factors use mr_indices_mod, only : nummr, mr_names - use log_mod, only : log_event, & + use log_mod, only : log_event, & LOG_LEVEL_DEBUG - use sci_geometric_constants_mod, & - only : get_panel_id, get_height_fe, & - get_height_fv, get_da_msl_proj - use io_config_mod, only : subroutine_timers, use_xios_io, write_fluxes + use sci_geometric_constants_mod, & + only : get_panel_id, & + get_height_fe, get_da_msl_proj + use io_config_mod, only : use_xios_io, write_fluxes use timer_mod, only : timer + use timing_mod, only : start_timing, stop_timing, tik, LPROF use transport_config_mod, only : transport_ageofair use driver_modeldb_mod, only : modeldb_type @@ -86,58 +87,55 @@ subroutine gungho_diagnostics_driver( modeldb, & type(mesh_type), intent(in), pointer :: twod_mesh logical, intent(in) :: nodal_output_on_w3 - type( field_collection_type ), pointer :: prognostic_fields => null() - type( field_collection_type ), pointer :: con_tracer_last_outer - type( field_collection_type ), pointer :: lbc_fields - type( field_collection_type ), pointer :: moisture_fields => null() - type( field_type ), pointer :: mr(:) => null() - type( field_type ), pointer :: moist_dyn(:) => null() - type( field_collection_type ), pointer :: derived_fields - - type( field_type), pointer :: theta => null() - type( field_type), pointer :: u => null() - type( field_type), pointer :: h_u => null() - type( field_type), pointer :: v_u => null() - type( field_type), pointer :: rho => null() - type( field_type), pointer :: exner => null() - type( field_type), pointer :: panel_id => null() - type( field_type), pointer :: height_w3 => null() - type( field_type), pointer :: height_wth => null() - type( field_type), pointer :: lbc_u => null() - type( field_type), pointer :: lbc_theta => null() - type( field_type), pointer :: lbc_rho => null() - type( field_type), pointer :: lbc_exner => null() - type( field_type), pointer :: lbc_m_v=> null() - type( field_type), pointer :: lbc_q=> null() - type( field_type), pointer :: u_in_w2h => null() - type( field_type), pointer :: v_in_w2h => null() - type( field_type), pointer :: w_in_wth => null() - type( field_type), pointer :: ageofair => null() - type( field_type), pointer :: exner_in_wth => null() - type( field_type), pointer :: dA => null() - - type(field_array_type), pointer :: mr_array => null() - type(field_array_type), pointer :: moist_dyn_array => null() + type(field_collection_type), pointer :: prognostic_fields + type(field_collection_type), pointer :: con_tracer_last_outer + type(field_collection_type), pointer :: lbc_fields + type(field_collection_type), pointer :: moisture_fields + type(field_type), pointer :: mr(:) + type(field_type), pointer :: moist_dyn(:) + type(field_collection_type), pointer :: derived_fields + + type(field_type), pointer :: theta + type(field_type), pointer :: u + type(field_type), pointer :: h_u + type(field_type), pointer :: v_u + type(field_type), pointer :: rho + type(field_type), pointer :: exner + type(field_type), pointer :: panel_id + type(field_type), pointer :: height + type(field_type), pointer :: lbc_u + type(field_type), pointer :: lbc_theta + type(field_type), pointer :: lbc_rho + type(field_type), pointer :: lbc_exner + type(field_type), pointer :: lbc_m_v + type(field_type), pointer :: lbc_q + type(field_type), pointer :: u_in_w2h + type(field_type), pointer :: v_in_w2h + type(field_type), pointer :: w_in_wth + type(field_type), pointer :: ageofair + type(field_type), pointer :: exner_in_wth + type(field_type), pointer :: dA + + type(field_array_type), pointer :: mr_array + type(field_array_type), pointer :: moist_dyn_array ! Iterator for field collection type(field_collection_iterator_type) :: iterator ! A pointer used for retrieving fields from collections ! when iterating over them - class( field_parent_type ), pointer :: field_ptr => null() + class(field_parent_type), pointer :: field_ptr + procedure(write_interface), pointer :: tmp_write_ptr + type(io_value_type), pointer :: temp_corr_io_value - type(io_value_type), pointer :: temp_corr_io_value + integer(kind=i_def) :: i, fs + integer(kind=tik) :: id + character(len=str_def) :: name, prefix, field_name - character(str_def) :: name + integer(kind=i_def), allocatable :: fs_ids(:) + character(len=str_def), allocatable :: fs_names(:) - integer :: fs - integer :: element_order_h, element_order_v - - procedure(write_interface), pointer :: tmp_write_ptr => null() - - integer :: i - - if ( subroutine_timers ) call timer('gungho_diagnostics_driver') + if ( LPROF ) call start_timing( id, 'gungho_diagnostics_driver' ) call log_event("Gungho: writing diagnostic output", LOG_LEVEL_DEBUG) @@ -161,20 +159,6 @@ subroutine gungho_diagnostics_driver( modeldb, & call prognostic_fields%get_field('rho', rho) call prognostic_fields%get_field('exner', exner) - ! Get element orders and get the finite element or finite volume height - element_order_h = theta%get_element_order_h() - element_order_v = theta%get_element_order_v() - - if (element_order_h > 0 .or. element_order_v > 0) then - ! Get the finite element height - height_w3 => get_height_fe(W3, mesh%get_id()) - height_wth => get_height_fe(Wtheta, mesh%get_id()) - else - ! Get the finite volume height - height_w3 => get_height_fv(W3, mesh%get_id()) - height_wth => get_height_fv(Wtheta, mesh%get_id()) - end if - ! Scalar fields call write_scalar_diagnostic('rho', rho, & modeldb%clock, mesh, nodal_output_on_w3) @@ -182,10 +166,31 @@ subroutine gungho_diagnostics_driver( modeldb, & modeldb%clock, mesh, nodal_output_on_w3) call write_scalar_diagnostic('exner', exner, & modeldb%clock, mesh, nodal_output_on_w3) - call write_scalar_diagnostic('height_w3', height_w3, & - modeldb%clock, mesh, nodal_output_on_w3) - call write_scalar_diagnostic('height_wth', height_wth, & - modeldb%clock, mesh, nodal_output_on_w3) + + ! Write out heights of function space DoFs, if requested + allocate(fs_names(4)) + allocate(fs_ids(4)) + fs_names = (/ "w0 ", "w2h", "w3 ", "wth" /) ! Spaces to align lengths + fs_ids = (/ W0, W2H, W3, Wtheta /) + if (use_xios_io) then + if (modeldb%clock%is_initialisation()) then + prefix = "init_" + else + prefix = "" + end if + tmp_write_ptr => write_field_generic + do i = 1, SIZE(fs_names) + field_name = trim(prefix)//"height_"//trim(fs_names(i)) + fs = fs_ids(i) + if (diagnostic_to_be_sampled(trim(field_name))) then + height => get_height_fe(fs, mesh%get_id()) + call height%set_write_behaviour(tmp_write_ptr) + call height%write_field(trim(field_name)) + end if + end do + end if + deallocate(fs_names) + deallocate(fs_ids) if (transport_ageofair) then call con_tracer_last_outer%get_field('ageofair',ageofair) @@ -212,13 +217,25 @@ subroutine gungho_diagnostics_driver( modeldb, & call u_in_w2h%set_write_behaviour(tmp_write_ptr) call v_in_w2h%set_write_behaviour(tmp_write_ptr) if (modeldb%clock%is_initialisation()) then - call u_in_w2h%write_field("init_u_in_w2h") - call v_in_w2h%write_field("init_v_in_w2h") - call w_in_wth%write_field("init_w_in_wth") + if (diagnostic_to_be_sampled("init_u_in_w2h")) then + call u_in_w2h%write_field("init_u_in_w2h") + end if + if (diagnostic_to_be_sampled("init_v_in_w2h")) then + call v_in_w2h%write_field("init_v_in_w2h") + end if + if (diagnostic_to_be_sampled("init_w_in_wth")) then + call w_in_wth%write_field("init_w_in_wth") + end if else - call u_in_w2h%write_field("u_in_w2h") - call v_in_w2h%write_field("v_in_w2h") - call w_in_wth%write_field("w_in_wth") + if (diagnostic_to_be_sampled("u_in_w2h")) then + call u_in_w2h%write_field("u_in_w2h") + end if + if (diagnostic_to_be_sampled("v_in_w2h")) then + call v_in_w2h%write_field("v_in_w2h") + end if + if (diagnostic_to_be_sampled("w_in_wth")) then + call w_in_wth%write_field("w_in_wth") + end if end if else call write_vector_diagnostic('u', u, & @@ -233,7 +250,7 @@ subroutine gungho_diagnostics_driver( modeldb, & ! Moisture fields if ( moisture_formulation /= moisture_formulation_dry ) then - do i=1,nummr + do i = 1, nummr call write_scalar_diagnostic( trim(mr_names(i)), mr(i), & modeldb%clock, mesh, nodal_output_on_w3 ) end do @@ -276,12 +293,12 @@ subroutine gungho_diagnostics_driver( modeldb, & modeldb%clock, mesh, nodal_output_on_w3) call write_vector_diagnostic('readlbc_h_u', h_u, & modeldb%clock, mesh, nodal_output_on_w3) - endif - endif + end if + end if ! Derived physics fields (only those on W3 or Wtheta) if (use_physics .and. use_xios_io .and. .not. modeldb%clock%is_initialisation()) then - + field_ptr => null() call iterator%initialise(derived_fields) do if ( .not.iterator%has_next() ) exit @@ -333,8 +350,7 @@ subroutine gungho_diagnostics_driver( modeldb, & call write_divergence_diagnostic( u, modeldb%clock, mesh ) call write_hydbal_diagnostic( theta, moist_dyn, exner, mesh ) end if - - if ( subroutine_timers ) call timer('gungho_diagnostics_driver') + if ( LPROF ) call stop_timing( id, 'gungho_diagnostics_driver' ) end subroutine gungho_diagnostics_driver end module gungho_diagnostics_driver_mod diff --git a/science/gungho/source/driver/gungho_driver_mod.F90 b/science/gungho/source/driver/gungho_driver_mod.F90 index a3b9846a6..2c1e5a37a 100644 --- a/science/gungho/source/driver/gungho_driver_mod.F90 +++ b/science/gungho/source/driver/gungho_driver_mod.F90 @@ -63,6 +63,9 @@ module gungho_driver_mod stochastic_physics, & stochastic_physics_um use io_value_mod, only : io_value_type + use time_config_mod, only : timestep_start + use timing_mod, only : start_timing, stop_timing, & + tik, LPROF #ifdef UM_PHYSICS use variable_fields_mod, only : update_variable_fields @@ -130,6 +133,7 @@ subroutine initialise( program_name, modeldb ) character(len=*), parameter :: io_context_name = "gungho_atm" integer(i_def) :: random_seed_size real(r_def), allocatable :: real_array(:) + integer(tik) :: id #ifdef UM_PHYSICS type( field_collection_type ), pointer :: field_collection_ptr @@ -140,6 +144,8 @@ subroutine initialise( program_name, modeldb ) nullify( field_collection_ptr, soil_fields, snow_fields, surface_fields ) #endif + call log_event('Initialising gungho', LOG_LEVEL_INFO) + if ( LPROF ) call start_timing(id, 'gungho_driver.initialise') ! Initialise infrastructure and setup constants call initialise_infrastructure( io_context_name, modeldb ) @@ -270,6 +276,7 @@ subroutine initialise( program_name, modeldb ) #endif nullify(mesh, twod_mesh, aerosol_mesh, aerosol_twod_mesh) + if ( LPROF ) call stop_timing(id, 'gungho_driver.initialise') end subroutine initialise @@ -286,6 +293,8 @@ subroutine step( modeldb ) type(mesh_type), pointer :: mesh => null() type(mesh_type), pointer :: twod_mesh => null() + integer(kind=i_def) :: ts_start, rc + integer(tik) :: tid_first, tid_rest #if defined(COUPLED) || defined(UM_PHYSICS) type( field_collection_type ), pointer :: depository => null() @@ -302,7 +311,17 @@ subroutine step( modeldb ) type( field_collection_type ), pointer :: surface_fields type( field_collection_type ), pointer :: ancil_fields +#endif + read(timestep_start,*,iostat=rc) ts_start + if ( LPROF ) then + if ( modeldb%clock%get_step() == ts_start ) then + call start_timing(tid_first, 'gungho_driver.first_timestep') + else + call start_timing(tid_rest, 'gungho_driver.timestep') + end if + end if +#ifdef UM_PHYSICS nullify( surface_fields, ancil_fields ) regrid_operation => map_scalar_intermesh @@ -427,6 +446,14 @@ subroutine step( modeldb ) nullify(mesh, twod_mesh) + if ( LPROF ) then + if ( modeldb%clock%get_step() == ts_start ) then + call stop_timing(tid_first, 'gungho_driver.first_timestep') + else + call stop_timing(tid_rest, 'gungho_driver.timestep') + end if + end if + end subroutine step !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -440,10 +467,15 @@ subroutine finalise( program_name, modeldb ) character(*), intent(in) :: program_name type(modeldb_type), intent(inout) :: modeldb + integer(tik) :: id #ifdef COUPLED type( field_collection_type ), pointer :: depository => null() +#endif + + if ( LPROF ) call start_timing(id, 'gungho_driver.finalise') +#ifdef COUPLED if (l_esm_couple) then depository => modeldb%fields%get_field_collection("depository") ! Ensure coupling fields are updated at the end of a cycle to ensure the values @@ -468,6 +500,9 @@ subroutine finalise( program_name, modeldb ) ! Finalise infrastructure and constants call finalise_infrastructure(modeldb) + call log_event('gungho finalised', LOG_LEVEL_INFO) + if ( LPROF ) call stop_timing(id, 'gungho_driver.finalise') + end subroutine finalise end module gungho_driver_mod diff --git a/science/gungho/source/driver/gungho_model_mod.F90 b/science/gungho/source/driver/gungho_model_mod.F90 index e91f0fbd6..00c9842f7 100644 --- a/science/gungho/source/driver/gungho_model_mod.F90 +++ b/science/gungho/source/driver/gungho_model_mod.F90 @@ -417,6 +417,7 @@ subroutine initialise_infrastructure( io_context_name, modeldb ) logical(l_def) :: mesh_already_exists integer(i_def) :: i, j, mesh_ctr + integer(i_def), allocatable :: stencil_depths(:) character(str_def), allocatable :: base_mesh_names(:) character(str_def), allocatable :: meshes_to_shift(:) character(str_def), allocatable :: meshes_to_double(:) @@ -445,7 +446,6 @@ subroutine initialise_infrastructure( io_context_name, modeldb ) integer(i_def) :: geometry integer(i_def) :: extrusion_method - integer(i_def) :: stencil_depth real(r_def) :: domain_bottom real(r_def) :: domain_height real(r_def) :: scaled_radius @@ -672,13 +672,17 @@ subroutine initialise_infrastructure( io_context_name, modeldb ) apply_partition_check = .true. end if - stencil_depth = get_required_stencil_depth() + allocate(stencil_depths(size(base_mesh_names))) + call get_required_stencil_depth( & + stencil_depths, base_mesh_names, modeldb%configuration & + ) + call init_mesh( modeldb%configuration, & modeldb%mpi%get_comm_rank(), & modeldb%mpi%get_comm_size(), & base_mesh_names, & extrusion, & - get_required_stencil_depth(), & + stencil_depths, & apply_partition_check ) @@ -922,6 +926,7 @@ subroutine initialise_infrastructure( io_context_name, modeldb ) chi_inventory, panel_id_inventory, files_init_ptr, & orography_mesh, orography_twod_mesh) deallocate(base_mesh_names) + deallocate(stencil_depths) if (allocated(meshes_to_shift)) deallocate(meshes_to_shift) if (allocated(meshes_to_double)) deallocate(meshes_to_double) diff --git a/science/gungho/source/driver/gungho_step_mod.x90 b/science/gungho/source/driver/gungho_step_mod.x90 index da004ab84..82b475792 100644 --- a/science/gungho/source/driver/gungho_step_mod.x90 +++ b/science/gungho/source/driver/gungho_step_mod.x90 @@ -57,6 +57,8 @@ module gungho_step_mod use compute_total_energy_alg_mod, only : compute_total_energy_alg use compute_total_mass_alg_mod, only : compute_total_mass_alg use sci_field_minmax_alg_mod, only : log_field_minmax + use timing_mod, only : start_timing, stop_timing, & + tik, LPROF implicit none @@ -110,6 +112,9 @@ module gungho_step_mod real( r_def ) :: dt logical( l_def ) :: use_moisture + integer( tik ) :: id + + if ( LPROF ) call start_timing( id, 'gungho_timestep' ) write( log_scratch_space, '("/", A, "\ ")' ) repeat( "*", 76 ) call log_event( log_scratch_space, LOG_LEVEL_TRACE ) @@ -117,11 +122,13 @@ module gungho_step_mod '(A,I0)' ) 'Start of timestep ', model_clock%get_step() call log_event( log_scratch_space, LOG_LEVEL_INFO ) - temp_corr_io_value => get_io_value( modeldb%values, 'temperature_correction_io_value') - call modeldb%values%get_value( 'total_dry_mass', total_dry_mass ) - call modeldb%values%get_value( 'total_energy', total_energy ) - call modeldb%values%get_value( 'total_energy_previous', & - total_energy_previous ) + if ( encorr_usage /= encorr_usage_none .or. write_conservation_diag ) then + temp_corr_io_value => get_io_value( modeldb%values, 'temperature_correction_io_value') + call modeldb%values%get_value( 'total_dry_mass', total_dry_mass ) + call modeldb%values%get_value( 'total_energy', total_energy ) + call modeldb%values%get_value( 'total_energy_previous', & + total_energy_previous ) + end if use_moisture = ( moisture_formulation /= moisture_formulation_dry ) @@ -220,6 +227,7 @@ module gungho_step_mod call log_event( log_scratch_space, LOG_LEVEL_INFO ) write( log_scratch_space, '("\", A, "/ ")' ) repeat( "*", 76 ) call log_event( log_scratch_space, LOG_LEVEL_INFO ) + if ( LPROF ) call stop_timing( id, 'gungho_timestep' ) end subroutine gungho_step diff --git a/science/gungho/source/kernel/core_dynamics/assemble_w2h_from_w2hb_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/assemble_w2h_from_w2hb_kernel_mod.F90 new file mode 100644 index 000000000..7c4a6ffe4 --- /dev/null +++ b/science/gungho/source/kernel/core_dynamics/assemble_w2h_from_w2hb_kernel_mod.F90 @@ -0,0 +1,95 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief Maps a field from W2h broken to W2h. +!> @details Forms a continuous W2h field by adding the components from a +!! broken W2h field on either side of the mesh facets. +module assemble_w2h_from_w2hb_kernel_mod + + use argument_mod, only : arg_type, & + GH_FIELD, GH_REAL, & + GH_READ, GH_INC, & + CELL_COLUMN + use constants_mod, only : r_solver, i_def + use fs_continuity_mod, only : W2h, W2broken + use kernel_mod, only : kernel_type + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + !> The type declaration for the kernel. Contains the metadata needed by the + !> Psy layer. + !> + type, public, extends(kernel_type) :: assemble_w2h_from_w2hb_kernel_type + private + type(arg_type) :: meta_args(2) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2h), & ! field_w2h + arg_type(GH_FIELD, GH_REAL, GH_READ, W2broken) & ! field_w2h_broken + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: assemble_w2h_from_w2hb_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: assemble_w2h_from_w2hb_code + +contains + +!> @brief Converts a broken W2h field into a continuous W2h field +!> +!> @param[in] nlayers Number of layers in the mesh +!> @param[in,out] field_w2h Field in the W2h space to be returned. +!> @param[in] field_w2h_broken Original field in W2h broken to be used. +!> @param[in] ndf_w2h Number of degrees of freedom per cell for W2h +!> @param[in] undf_w2h Number of (local) unique degrees of freedom for W2h +!> @param[in] map_w2h Dofmap for the cell at the base of the column for W2h +!> @param[in] ndf_w2h_broken Number of degrees of freedom per cell for W2h broken +!> @param[in] undf_w2h_broken Number of (local) unique degrees of freedom for W2h broken +!> @param[in] map_w2h_broken Dofmap for the cell at the base of the column for W2h broken +subroutine assemble_w2h_from_w2hb_code( nlayers, & + field_w2h, & + field_w2h_broken, & + ndf_w2h, & + undf_w2h, & + map_w2h, & + ndf_w2h_broken, & + undf_w2h_broken, & + map_w2h_broken & + ) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: ndf_w2h_broken, ndf_w2h + integer(kind=i_def), intent(in) :: undf_w2h_broken, undf_w2h + integer(kind=i_def), dimension(ndf_w2h_broken), intent(in) :: map_w2h_broken + integer(kind=i_def), dimension(ndf_w2h), intent(in) :: map_w2h + + real(kind=r_solver), dimension(undf_w2h), intent(inout) :: field_w2h + real(kind=r_solver), dimension(undf_w2h_broken), intent(in) :: field_w2h_broken + + ! Internal variables + integer(kind=i_def) :: df, k + + ! Loop over horizontal W2h DoFs + do df = 1, ndf_w2h + ! Loop over layers of mesh + do k = 0, nlayers - 1 + field_w2h(map_w2h(df)+k) = field_w2h(map_w2h(df)+k) & + + field_w2h_broken(map_w2h_broken(df)+k) + end do + end do + +end subroutine assemble_w2h_from_w2hb_code + +end module assemble_w2h_from_w2hb_kernel_mod diff --git a/science/gungho/source/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod.F90 index 9ca14d532..408a5ac63 100644 --- a/science/gungho/source/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod.F90 @@ -27,14 +27,16 @@ module compute_coriolis_matrix_kernel_mod GH_BASIS, GH_DIFF_BASIS, & CELL_COLUMN, GH_QUADRATURE_XYoZ use fs_continuity_mod, only: W2 - use sci_coordinate_jacobian_mod, only: coordinate_jacobian -use base_mesh_config_mod, only: geometry, & - geometry_spherical use rotation_vector_mod, only: rotation_vector_fplane, & rotation_vector_sphere use cross_product_mod, only: cross_product +use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical +use finite_element_config_mod, only: coord_system +use planet_config_mod, only: scaled_radius + implicit none private @@ -167,8 +169,10 @@ subroutine compute_coriolis_matrix_code(cell, nlayers, ncell_3d, & end if ! Calculate the Jacobian and its determinant - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & - chi_1_e, chi_2_e, chi_3_e, ipanel, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & + chi_1_e, chi_2_e, chi_3_e, ipanel, & basis_chi, diff_basis_chi, jac, dj) diff --git a/science/gungho/source/kernel/core_dynamics/compute_dl_matrix_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/compute_dl_matrix_kernel_mod.F90 index 74064b04e..550cbda86 100644 --- a/science/gungho/source/kernel/core_dynamics/compute_dl_matrix_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/compute_dl_matrix_kernel_mod.F90 @@ -20,15 +20,19 @@ module compute_dl_matrix_kernel_mod GH_BASIS, GH_DIFF_BASIS, & GH_SCALAR, GH_INTEGER, & CELL_COLUMN, GH_QUADRATURE_XYoZ - use base_mesh_config_mod, only: geometry, geometry_spherical use constants_mod, only: i_def, r_def, r_second, & PI, degrees_to_radians use sci_chi_transform_mod, only: chi2llr - use damping_layer_config_mod, only: dl_type, dl_type_latitude use fs_continuity_mod, only: W2 use kernel_mod, only: kernel_type use sci_coordinate_jacobian_mod, only: coordinate_jacobian + use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical + use damping_layer_config_mod, only: dl_type, dl_type_latitude + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -169,6 +173,9 @@ subroutine compute_dl_matrix_code(cell, nlayers, ncell_3d, & real(kind=r_def) :: z real(kind=r_def), dimension(nqp_h,nqp_v) :: dj real(kind=r_def), dimension(3,3,nqp_h,nqp_v) :: jac + real(kind=r_def) :: wt + real(kind=r_def) :: j_v1(3), j_v2(3) + real(kind=r_def) :: factor(ndf_w2) integer(kind=i_def) :: ipanel @@ -180,76 +187,82 @@ subroutine compute_dl_matrix_code(cell, nlayers, ncell_3d, & ndof_vol = 2*element_order_h*(element_order_h+1)*(element_order_v+1) & + (element_order_h+1)*(element_order_h+1)*element_order_v + + ! Only modify dofs corresponding to vertical part of w-basis + ! function (for lowest order: final two dofs). + ! Dofs are ordered: + ! a) Horizontal volume dofs + ! b) Vertical volume dofs + ! c) Horizontal face dofs + ! d) Vertical face dofs + ! So vertical dofs follow one of the two conditions: + ! b) df > ndof_vol_h .and. df <= ndof_vol + ! d) df > ndf_w2 - 2*ndof_face_v + ! So the check is as follows + do df = 1, ndf_w2 + if ( (df > ndf_w2 - 2*ndof_face_v) .or. & + (df > ndof_vol_h .and. df <= ndof_vol) ) then + factor(df) = real(dt, r_def) + else + factor(df) = 0.0_r_def + end if + end do + + ! Loop over layers: Start from 1 as in this loop k is not an offset do k = 1, nlayers - ik = k + (cell-1)*nlayers ! Indirect the chi coord field here do df = 1, ndf_chi chi1_e(df) = chi1(map_chi(df) + k - 1) chi2_e(df) = chi2(map_chi(df) + k - 1) chi3_e(df) = chi3(map_chi(df) + k - 1) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, basis_chi, diff_basis_chi, jac, dj) + ik = k + (cell-1)*nlayers + mm(ik, :, :) = 0.0_r_def ! Only use dofs corresponding to vertical part of basis function - do df2 = 1, ndf_w2 - do df = 1, ndf_w2 ! Mass matrix is not symmetric for damping layer - mm(ik,df,df2) = 0.0_r_def - do qp2 = 1, nqp_v - do qp1 = 1, nqp_h - chi1_at_quad = 0.0_r_def - chi2_at_quad = 0.0_r_def - chi3_at_quad = 0.0_r_def - do dfc = 1,ndf_chi - chi1_at_quad = chi1_at_quad + chi1_e(dfc)*basis_chi(1,dfc,qp1,qp2) - chi2_at_quad = chi2_at_quad + chi2_e(dfc)*basis_chi(1,dfc,qp1,qp2) - chi3_at_quad = chi3_at_quad + chi3_e(dfc)*basis_chi(1,dfc,qp1,qp2) - end do - - if (geometry == geometry_spherical) then - - call chi2llr(chi1_at_quad,chi2_at_quad,chi3_at_quad, & - ipanel, long_at_quad,lat_at_quad,r_at_quad) - z=r_at_quad - radius - - if (dl_type == dl_type_latitude) then - mu_at_quad = damping_layer_func(z, dl_strength, & - dl_base_height, domain_height, lat_at_quad) - else - mu_at_quad = damping_layer_func(z, dl_strength, & - dl_base_height, domain_height, 0.0_r_def) - end if - else - mu_at_quad = damping_layer_func(chi3_at_quad, dl_strength, & - dl_base_height, domain_height, 0.0_r_def) - end if - - integrand = wqp_h(qp1) * wqp_v(qp2) * & - dot_product( & - matmul(jac(:,:,qp1,qp2),basis_w2(:,df,qp1,qp2)), & - matmul(jac(:,:,qp1,qp2),basis_w2(:,df2,qp1,qp2)) ) & - /dj(qp1,qp2) - - ! Only modify dofs corresponding to vertical part of w-basis - ! function (for lowest order: final two dofs). - ! Dofs are ordered: - ! a) Horizontal volume dofs - ! b) Vertical volume dofs - ! c) Horizontal face dofs - ! d) Vertical face dofs - ! So vertical dofs follow one of the two conditions: - ! b) df > ndof_vol_h .and. df <= ndof_vol - ! d) df > ndf_w2 - 2*ndof_face_v - ! So the check is as follows - if ( (df > ndf_w2 - 2*ndof_face_v) .or. & - (df > ndof_vol_h .and. df <= ndof_vol) ) then - mm(ik,df,df2) = mm(ik,df,df2) & - + (1.0_r_def + real(dt, r_def)*mu_at_quad) & - * integrand - else - mm(ik,df,df2) = mm(ik,df,df2) + integrand - end if + do qp2 = 1, nqp_v + do qp1 = 1, nqp_h + chi1_at_quad = 0.0_r_def + chi2_at_quad = 0.0_r_def + chi3_at_quad = 0.0_r_def + do dfc = 1,ndf_chi + chi1_at_quad = chi1_at_quad + chi1_e(dfc)*basis_chi(1,dfc,qp1,qp2) + chi2_at_quad = chi2_at_quad + chi2_e(dfc)*basis_chi(1,dfc,qp1,qp2) + chi3_at_quad = chi3_at_quad + chi3_e(dfc)*basis_chi(1,dfc,qp1,qp2) + end do + + if (geometry == geometry_spherical) then + + call chi2llr(chi1_at_quad, chi2_at_quad, chi3_at_quad, & + ipanel, long_at_quad, lat_at_quad, r_at_quad) + z = r_at_quad - radius + + if (dl_type == dl_type_latitude) then + mu_at_quad = damping_layer_func(z, dl_strength, & + dl_base_height, domain_height, lat_at_quad) + else + mu_at_quad = damping_layer_func(z, dl_strength, & + dl_base_height, domain_height, 0.0_r_def) + end if + else + mu_at_quad = damping_layer_func(chi3_at_quad, dl_strength, & + dl_base_height, domain_height, 0.0_r_def) + end if + + wt = wqp_h(qp1) * wqp_v(qp2) / dj(qp1,qp2) + do df2 = 1, ndf_w2 + j_v2 = matmul(jac(:,:,qp1,qp2),basis_w2(:,df2,qp1,qp2)) + do df = 1, ndf_w2 ! Mass matrix is not symmetric for damping layer + j_v1 = matmul(jac(:,:,qp1,qp2),basis_w2(:,df,qp1,qp2)) + + integrand = wt * dot_product( j_v1, j_v2 ) + mm(ik,df,df2) = mm(ik,df,df2) & + + (1.0_r_def + factor(df)*mu_at_quad) & + * integrand end do end do end do @@ -281,12 +294,12 @@ function damping_layer_func(height, dl_strength, dl_base_height, domain_height, real(kind=r_def) :: height_star ! Latitude over which to reduce damping height from dl_base_height ! chosen to reduce it to approximately dl_base_height/2 - real(kind=r_def), parameter :: taper_lat = 50.0_r_def + real(kind=r_def), parameter :: taper_lat = 50.0_r_def*degrees_to_radians - if (abs(latitude) < taper_lat*degrees_to_radians) then + if (abs(latitude) < taper_lat) then height_star = domain_height + (height-domain_height)*cos(latitude) else - height_star = domain_height + (height-domain_height)*cos(taper_lat*degrees_to_radians) + height_star = domain_height + (height-domain_height)*cos(taper_lat) end if if (height_star >= dl_base_height) then diff --git a/science/gungho/source/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod.F90 index dff2de0b4..71785a9b0 100644 --- a/science/gungho/source/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod.F90 @@ -28,15 +28,17 @@ module compute_vert_coriolis_matrix_kernel_mod GH_BASIS, GH_DIFF_BASIS, & CELL_COLUMN, GH_QUADRATURE_XYoZ use fs_continuity_mod, only: W2, Wtheta - use sci_coordinate_jacobian_mod, only: coordinate_jacobian -use base_mesh_config_mod, only: geometry, & - geometry_spherical use rotation_vector_mod, only: rotation_vector_fplane, & rotation_vector_sphere, & vert_vector_sphere use cross_product_mod, only: cross_product +use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical +use finite_element_config_mod, only: coord_system +use planet_config_mod, only: scaled_radius + implicit none private @@ -180,8 +182,10 @@ subroutine compute_vert_coriolis_matrix_code(col_idx, nlayers, ncell_3d, & end if ! Calculate the Jacobian - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & - chi_1_e, chi_2_e, chi_3_e, ipanel, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & + chi_1_e, chi_2_e, chi_3_e, ipanel, & basis_chi, diff_basis_chi, jac, dj) ! To convert from reference space to physical space: diff --git a/science/gungho/source/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod.F90 index a692c28b5..8022dbe03 100644 --- a/science/gungho/source/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod.F90 @@ -32,6 +32,10 @@ module kinetic_energy_gradient_kernel_mod use fs_continuity_mod, only : W2 use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -152,7 +156,8 @@ subroutine kinetic_energy_gradient_code(nlayers, & chi_2_e(df) = chi_2( loc ) chi_3_e(df) = chi_3( loc ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) do df = 1, ndf_w2 diff --git a/science/gungho/source/kernel/core_dynamics/project_eos_pressure_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/project_eos_pressure_kernel_mod.F90 index af05571eb..ffe8eb68a 100644 --- a/science/gungho/source/kernel/core_dynamics/project_eos_pressure_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/project_eos_pressure_kernel_mod.F90 @@ -19,6 +19,10 @@ module project_eos_pressure_kernel_mod use fs_continuity_mod, only : W3, Wtheta use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -158,7 +162,8 @@ subroutine project_eos_pressure_code(cell, nlayers, chi2_e(df) = chi2(map_chi(df) + k) chi3_e(df) = chi3(map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) do df = 1, ndf_w3 diff --git a/science/gungho/source/kernel/core_dynamics/project_eos_rho_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/project_eos_rho_kernel_mod.F90 index 3c34582d0..b380f84fa 100644 --- a/science/gungho/source/kernel/core_dynamics/project_eos_rho_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/project_eos_rho_kernel_mod.F90 @@ -16,10 +16,14 @@ module project_eos_rho_kernel_mod GH_BASIS, GH_DIFF_BASIS, GH_SCALAR, & CELL_COLUMN, GH_QUADRATURE_XYoZ use constants_mod, only : r_def, i_def -use idealised_config_mod, only : test use fs_continuity_mod, only : WTHETA, W3 use kernel_mod, only : kernel_type +use base_mesh_config_mod, only: geometry, topology +use finite_element_config_mod, only: coord_system +use idealised_config_mod, only: test +use planet_config_mod, only: scaled_radius + implicit none !------------------------------------------------------------------------------- @@ -159,7 +163,9 @@ subroutine project_eos_rho_code(nlayers, & chi3_e(df) = chi3( map_chi(df) + k ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & chi1_e, chi2_e, chi3_e, & ipanel, chi_basis, chi_diff_basis, & jac, dj ) diff --git a/science/gungho/source/kernel/core_dynamics/rhs_project_eos_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/rhs_project_eos_kernel_mod.F90 index c0bcd137f..108a17051 100644 --- a/science/gungho/source/kernel/core_dynamics/rhs_project_eos_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/rhs_project_eos_kernel_mod.F90 @@ -22,6 +22,10 @@ module rhs_project_eos_kernel_mod use fs_continuity_mod, only : W3, Wtheta use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -168,7 +172,8 @@ subroutine rhs_project_eos_code(nlayers, & chi2_e(df) = chi2(map_chi(df) + k) chi3_e(df) = chi3(map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) do df = 1, ndf_wt theta_vd_e(df) = theta(map_wt(df) + k) * moist_dyn_gas(map_wt(df) + k) diff --git a/science/gungho/source/kernel/core_dynamics/vorticity_rhs_kernel_mod.F90 b/science/gungho/source/kernel/core_dynamics/vorticity_rhs_kernel_mod.F90 index d70d25f2d..ab31b0f5e 100644 --- a/science/gungho/source/kernel/core_dynamics/vorticity_rhs_kernel_mod.F90 +++ b/science/gungho/source/kernel/core_dynamics/vorticity_rhs_kernel_mod.F90 @@ -21,6 +21,10 @@ module vorticity_rhs_kernel_mod use fs_continuity_mod, only : W1, W2 use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -148,7 +152,8 @@ subroutine vorticity_rhs_code(nlayers, & chi_2_e(df) = chi_2( loc ) chi_3_e(df) = chi_3( loc ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & ipanel, basis_chi, diff_basis_chi, jac, dj) do df = 1, ndf_u u_cell(df) = u( map_u(df) + k ) diff --git a/science/gungho/source/kernel/diagnostics/compute_energetics_kernel_mod.f90 b/science/gungho/source/kernel/diagnostics/compute_energetics_kernel_mod.f90 index 121490e96..a7d49fa39 100644 --- a/science/gungho/source/kernel/diagnostics/compute_energetics_kernel_mod.f90 +++ b/science/gungho/source/kernel/diagnostics/compute_energetics_kernel_mod.f90 @@ -30,6 +30,10 @@ module compute_energetics_kernel_mod use fs_continuity_mod, only : W2, W3, Wtheta use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -219,7 +223,8 @@ subroutine compute_energetics_code( & chi_2_e(df) = chi_2( loc ) chi_3_e(df) = chi_3( loc ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) do df = 1, ndf_w3 diff --git a/science/gungho/source/kernel/diagnostics/compute_entropy_kernel_mod.F90 b/science/gungho/source/kernel/diagnostics/compute_entropy_kernel_mod.F90 index 478eb4676..89a92b82b 100644 --- a/science/gungho/source/kernel/diagnostics/compute_entropy_kernel_mod.F90 +++ b/science/gungho/source/kernel/diagnostics/compute_entropy_kernel_mod.F90 @@ -22,6 +22,10 @@ module compute_entropy_kernel_mod use fs_continuity_mod, only : W3, Wtheta use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -160,7 +164,8 @@ subroutine compute_entropy_code( nlayers, & chi_2_e(df) = chi_2( loc ) chi_3_e(df) = chi_3( loc ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) do df = 1, ndf_wtheta diff --git a/science/gungho/source/kernel/diagnostics/compute_moist_mass_kernel_mod.F90 b/science/gungho/source/kernel/diagnostics/compute_moist_mass_kernel_mod.F90 index 57da7183a..5327c8ce1 100644 --- a/science/gungho/source/kernel/diagnostics/compute_moist_mass_kernel_mod.F90 +++ b/science/gungho/source/kernel/diagnostics/compute_moist_mass_kernel_mod.F90 @@ -21,6 +21,10 @@ module compute_moist_mass_kernel_mod use fs_continuity_mod, only : W3, Wtheta use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -153,7 +157,8 @@ subroutine compute_moist_mass_code( chi_3_e(df) = chi_3(l) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) ! Loop through dofs, grabbing the values for this cell for reference element diff --git a/science/gungho/source/kernel/diagnostics/compute_total_aam_kernel_mod.F90 b/science/gungho/source/kernel/diagnostics/compute_total_aam_kernel_mod.F90 index cca143aaa..786b4f2d8 100644 --- a/science/gungho/source/kernel/diagnostics/compute_total_aam_kernel_mod.F90 +++ b/science/gungho/source/kernel/diagnostics/compute_total_aam_kernel_mod.F90 @@ -25,6 +25,10 @@ module compute_total_aam_kernel_mod use fs_continuity_mod, only : W2, W3 use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -168,7 +172,9 @@ subroutine compute_total_aam_code( & chi_3_e(df) = chi_3( loc ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & chi_1_e, chi_2_e, chi_3_e, ipanel, & chi_basis, chi_diff_basis, jac, dj) do df = 1, ndf_w3 diff --git a/science/gungho/source/kernel/diagnostics/compute_total_pv_kernel_mod.F90 b/science/gungho/source/kernel/diagnostics/compute_total_pv_kernel_mod.F90 index 781ce8115..56b5c9cc8 100644 --- a/science/gungho/source/kernel/diagnostics/compute_total_pv_kernel_mod.F90 +++ b/science/gungho/source/kernel/diagnostics/compute_total_pv_kernel_mod.F90 @@ -19,13 +19,15 @@ module compute_total_pv_kernel_mod use constants_mod, only : r_def, i_def use fs_continuity_mod, only : W0, W1, W3 use kernel_mod, only : kernel_type - use base_mesh_config_mod, & - only: geometry, & - geometry_spherical use rotation_vector_mod, & only: rotation_vector_fplane, & rotation_vector_sphere + use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -180,7 +182,8 @@ subroutine compute_total_pv_code( chi2_e(df) = chi2( map_chi(df) + k ) chi3_e(df) = chi3( map_chi(df) + k ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) call coordinate_jacobian_inverse(nqp_h, nqp_v, jac, dj, jac_inv) diff --git a/science/gungho/source/kernel/initialisation/initial_streamfunc_kernel_mod.F90 b/science/gungho/source/kernel/initialisation/initial_streamfunc_kernel_mod.F90 index c44406bd0..e6f53573f 100644 --- a/science/gungho/source/kernel/initialisation/initial_streamfunc_kernel_mod.F90 +++ b/science/gungho/source/kernel/initialisation/initial_streamfunc_kernel_mod.F90 @@ -20,6 +20,12 @@ module initial_streamfunc_kernel_mod use kernel_mod, only : kernel_type use initial_wind_config_mod, only : profile +use base_mesh_config_mod, only: geometry, topology, & + geometry_planar, & + geometry_spherical +use finite_element_config_mod, only: coord_system +use planet_config_mod, only: scaled_radius + implicit none private @@ -108,9 +114,6 @@ subroutine initial_streamfunc_code(nlayers, & ) use analytic_streamfunction_profiles_mod, only: analytic_streamfunction - use base_mesh_config_mod, only: geometry, & - geometry_planar, & - geometry_spherical use sci_chi_transform_mod, only: chi2llr use sci_coordinate_jacobian_mod, only: coordinate_jacobian, & coordinate_jacobian_inverse @@ -169,7 +172,11 @@ subroutine initial_streamfunc_code(nlayers, & end do - call coordinate_jacobian(ndf_chi, & + call coordinate_jacobian(coord_system, & + geometry, & + topology, & + scaled_radius, & + ndf_chi, & nqp_h, & nqp_v, & chi_1_cell, & diff --git a/science/gungho/source/kernel/initialisation/initial_u_kernel_mod.F90 b/science/gungho/source/kernel/initialisation/initial_u_kernel_mod.F90 index f154a0606..ca19b15bb 100644 --- a/science/gungho/source/kernel/initialisation/initial_u_kernel_mod.F90 +++ b/science/gungho/source/kernel/initialisation/initial_u_kernel_mod.F90 @@ -20,11 +20,16 @@ module initial_u_kernel_mod CELL_COLUMN, GH_QUADRATURE_XYoZ use constants_mod, only : r_def, i_def, PI use fs_continuity_mod, only : W2 - use initial_wind_config_mod, only : profile_sin_uv, & - profile, sbr_angle_lat, sbr_angle_lon, & - u0, v0, shear, wavelength use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology, & + geometry_spherical + use finite_element_config_mod, only: coord_system + use initial_wind_config_mod, only: profile_sin_uv, profile, & + sbr_angle_lat, sbr_angle_lon, & + u0, v0, shear, wavelength + use planet_config_mod, only: scaled_radius + implicit none private @@ -106,8 +111,6 @@ subroutine initial_u_code(nlayers, & ) use analytic_wind_profiles_mod, only : analytic_wind - use base_mesh_config_mod, only : geometry, & - geometry_spherical use sci_chi_transform_mod, only : chi2llr use sci_coordinate_jacobian_mod, only : coordinate_jacobian use coord_transform_mod, only : sphere2cart_vector @@ -175,7 +178,11 @@ subroutine initial_u_code(nlayers, & chi_3_cell(df) = chi_3( map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, & + call coordinate_jacobian(coord_system, & + geometry, & + topology, & + scaled_radius, & + ndf_chi, & nqp_h, & nqp_v, & chi_1_cell, & diff --git a/science/gungho/source/kernel/initialisation/set_exner_kernel_mod.F90 b/science/gungho/source/kernel/initialisation/set_exner_kernel_mod.F90 index ebbde1980..692fda7c8 100644 --- a/science/gungho/source/kernel/initialisation/set_exner_kernel_mod.F90 +++ b/science/gungho/source/kernel/initialisation/set_exner_kernel_mod.F90 @@ -16,9 +16,13 @@ module set_exner_kernel_mod CELL_COLUMN, GH_QUADRATURE_XYoZ use constants_mod, only : r_def, i_def use fs_continuity_mod, only : W3 - use idealised_config_mod, only : test use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use idealised_config_mod, only: test + use planet_config_mod, only: scaled_radius + implicit none private @@ -142,7 +146,9 @@ subroutine set_exner_code(nlayers, & chi_2_e(df1) = chi_2(map_chi(df1) + k) chi_3_e(df1) = chi_3(map_chi(df1) + k) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, & jac, dj) diff --git a/science/gungho/source/kernel/initialisation/set_rho_kernel_mod.F90 b/science/gungho/source/kernel/initialisation/set_rho_kernel_mod.F90 index bc6f1bf39..90ec2182b 100644 --- a/science/gungho/source/kernel/initialisation/set_rho_kernel_mod.F90 +++ b/science/gungho/source/kernel/initialisation/set_rho_kernel_mod.F90 @@ -17,9 +17,12 @@ module set_rho_kernel_mod CELL_COLUMN, GH_QUADRATURE_XYoZ use fs_continuity_mod, only : Wchi use constants_mod, only : r_def, i_def - use idealised_config_mod, only : test use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use idealised_config_mod, only: test + use planet_config_mod, only: scaled_radius implicit none private @@ -142,7 +145,9 @@ subroutine set_rho_code(nlayers, rho, & chi_2_e(df1) = chi_2( map_chi(df1) + k ) chi_3_e(df1) = chi_3( map_chi(df1) + k ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, & + call coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, & chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, & jac, dj) diff --git a/science/gungho/source/kernel/solver/apply_mixed_u_operator_kernel_mod.F90 b/science/gungho/source/kernel/solver/apply_mixed_u_operator_kernel_mod.F90 new file mode 100644 index 000000000..fb51ad119 --- /dev/null +++ b/science/gungho/source/kernel/solver/apply_mixed_u_operator_kernel_mod.F90 @@ -0,0 +1,157 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +!> @brief Compute the LHS of the semi-implicit system for the horizontal velocity: +!! lhs_uv = norm_u*(Mu*u - P2t*t - grad*p), +!! with t = -Mt^(-1) * Pt2*u +module apply_mixed_u_operator_kernel_mod + +use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_READ, & + GH_WRITE, & + GH_REAL, CELL_COLUMN +use constants_mod, only : r_solver, i_def +use kernel_mod, only : kernel_type +use fs_continuity_mod, only : W2, W3, W2h, W2v, W2broken + +implicit none +private + +!------------------------------------------------------------------------------- +! Public types +!------------------------------------------------------------------------------- + +type, public, extends(kernel_type) :: apply_mixed_u_operator_kernel_type + private + type(arg_type) :: meta_args(7) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_WRITE, W2broken), & ! lhs_uv + arg_type(GH_FIELD, GH_REAL, GH_READ, W2h), & ! uv' + arg_type(GH_FIELD, GH_REAL, GH_READ, W2v), & ! w' + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! exner' + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W2, W2), & ! Mu^{c,d} + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W2, W3), & ! grad + arg_type(GH_FIELD, GH_REAL, GH_READ, W2) & ! norm_u + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: apply_mixed_u_operator_code +end type + +!------------------------------------------------------------------------------- +! Contained functions/subroutines +!------------------------------------------------------------------------------- +public :: apply_mixed_u_operator_code + +contains + +!> @brief Compute the LHS of the semi-implicit system +!> @param[in] cell Horizontal cell index +!> @param[in] nlayers Number of layers +!> @param[in,out] lhs_uv Mixed operator applied to the horizontal momentum equation +!> @param[in] wind_uv Horizontal wind field +!> @param[in] wind_w Vertical wind field +!> @param[in] exner Exner pressure field +!> @param[in] ncell1 Total number of cells for the mu_cd operator +!> @param[in] mu_cd Generalised mass matrix for the momentum equation +!> @param[in] ncell2 Total number of cells for the grad operator +!> @param[in] grad Generalised gradient operator for the momentum equation +!> @param[in] norm_u Normalisation field for the momentum equation +!> @param[in] ndf_w2hb number of degrees of freedom per cell for the broken horizontal wind space +!> @param[in] undf_w2hb unique number of degrees of freedom for the broken horizontal wind space +!> @param[in] map_w2hb dofmap for the cell at the base of the column for the broken horizontal wind space +!> @param[in] ndf_w2h number of degrees of freedom per cell for the horizontal wind space +!> @param[in] undf_w2h unique number of degrees of freedom for the horizontal wind space +!> @param[in] map_w2h dofmap for the cell at the base of the column for the horizontal wind space +!> @param[in] ndf_w2v Number of degrees of freedom per cell for the vertical wind space +!> @param[in] undf_w2v Unique number of degrees of freedom for the vertical wind space +!> @param[in] map_w2v Dofmap for the cell at the base of the column for the vertical wind space +!> @param[in] ndf_w3 Norm_umber of degrees of freedom per cell for the pressure space +!> @param[in] ndf_w3 Unique number of degrees of freedom for the pressure space +!> @param[in] map_w3 Dofmap for the cell at the base of the column for the pressure space +!> @param[in] ndf_w2 Number of degrees of freedom per cell for the 3d wind space +!> @param[in] undf_w2 Unique number of degrees of freedom for the 3d wind space +!> @param[in] map_w2 Dofmap for the cell at the base of the column for the 3d wind space + +subroutine apply_mixed_u_operator_code(cell, & + nlayers, & + lhs_uv, & + wind_uv, wind_w, exner, & + ncell1, mu_cd, & + ncell2, grad, & + norm_u, & + ndf_w2hb, undf_w2hb, map_w2hb, & + ndf_w2h, undf_w2h, map_w2h, & + ndf_w2v, undf_w2v, map_w2v, & + ndf_w3, undf_w3, map_w3, & + ndf_w2, undf_w2, map_w2) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: cell, nlayers + integer(kind=i_def), intent(in) :: ncell1, ncell2 + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + integer(kind=i_def), intent(in) :: undf_w2h, ndf_w2h + integer(kind=i_def), intent(in) :: undf_w2hb, ndf_w2hb + integer(kind=i_def), intent(in) :: undf_w2v, ndf_w2v + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w2hb), intent(in) :: map_w2hb + integer(kind=i_def), dimension(ndf_w2h), intent(in) :: map_w2h + integer(kind=i_def), dimension(ndf_w2v), intent(in) :: map_w2v + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + + ! Fields + real(kind=r_solver), dimension(undf_w2hb), intent(inout) :: lhs_uv + real(kind=r_solver), dimension(undf_w2h), intent(in) :: wind_uv + real(kind=r_solver), dimension(undf_w2v), intent(in) :: wind_w + real(kind=r_solver), dimension(undf_w2), intent(in) :: norm_u + real(kind=r_solver), dimension(undf_w3), intent(in) :: exner + + ! Operators + real(kind=r_solver), dimension(ncell1, ndf_w2, ndf_w2), intent(in) :: mu_cd + real(kind=r_solver), dimension(ncell2, ndf_w2, ndf_w3), intent(in) :: grad + + ! Internal variables + integer(kind=i_def) :: df, df2, ij, & + nm1, iw3, & + iw2, iw2h + + ! Set up some useful shorthands for indices + ij = (cell-1)*nlayers + 1 + nm1 = nlayers-1 + iw3 = map_w3(1) + + ! LHS UV + do df = 1, ndf_w2h + iw2h = map_w2hb(df) + iw2 = map_w2(df) + lhs_uv(iw2h:iw2h+nm1) = - norm_u(iw2:iw2+nm1) & + *grad(ij:ij+nm1, df, 1)*exner(iw3:iw3+nm1) + end do + do df2 = 1, ndf_w2h + do df = 1, ndf_w2h + iw2h = map_w2hb(df) + iw2 = map_w2(df) + lhs_uv(iw2h:iw2h+nm1) = lhs_uv(iw2h:iw2h+nm1) & + + norm_u(iw2:iw2+nm1)* & + mu_cd(ij:ij+nm1, df, df2)*wind_uv(map_w2h(df2):map_w2h(df2)+nm1) + end do + end do + do df2 = 1, ndf_w2v + do df = 1, ndf_w2h + iw2h = map_w2hb(df) + iw2 = map_w2(df) + lhs_uv(iw2h:iw2h+nm1) = lhs_uv(iw2h:iw2h+nm1) & + + norm_u(iw2:iw2+nm1)* & + mu_cd(ij:ij+nm1, df, ndf_w2h+df2)*wind_w(map_w2v(df2):map_w2v(df2)+nm1) + end do + end do + +end subroutine apply_mixed_u_operator_code + +end module apply_mixed_u_operator_kernel_mod diff --git a/science/gungho/source/kernel/solver/apply_mixed_wp_operator_kernel_mod.F90 b/science/gungho/source/kernel/solver/apply_mixed_wp_operator_kernel_mod.F90 new file mode 100644 index 000000000..afa1f1f7d --- /dev/null +++ b/science/gungho/source/kernel/solver/apply_mixed_wp_operator_kernel_mod.F90 @@ -0,0 +1,225 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +!> @brief Compute the LHS of the semi-implicit system for the +!! vertical velocity and pressure equations: +!! (lhs_w) = norm_u*(Mu*u - P2t*t - grad*p), +!! lhs_p = M3p*p - P3t*t + Q32*u, +!! with t = -Mt^(-1) * Pt2*u +module apply_mixed_wp_operator_kernel_mod + +use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_READ, & + GH_WRITE, & + GH_REAL, CELL_COLUMN +use constants_mod, only : r_solver, i_def +use kernel_mod, only : kernel_type +use fs_continuity_mod, only : W2, W3, Wtheta, W2h, W2v + +implicit none +private + +!------------------------------------------------------------------------------- +! Public types +!------------------------------------------------------------------------------- +type, public, extends(kernel_type) :: apply_mixed_wp_operator_kernel_type + private + type(arg_type) :: meta_args(14) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_WRITE, W2v), & ! lhs_w + arg_type(GH_FIELD, GH_REAL, GH_WRITE, W3), & ! lhs_p + arg_type(GH_FIELD, GH_REAL, GH_READ, W2h), & ! uv' + arg_type(GH_FIELD, GH_REAL, GH_READ, W2v), & ! w' + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! exner' + arg_type(GH_OPERATOR, GH_REAL, GH_READ, Wtheta, W2), & ! Ptheta2 + arg_type(GH_FIELD, GH_REAL, GH_READ, Wtheta), & ! Mtheta^-1 + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W2, W2), & ! Mu^{c,d} + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W2, Wtheta), & ! P2theta + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W2, W3), & ! grad + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! norm_u + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W3, W3), & ! m3p + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W3, W2), & ! q32 + arg_type(GH_OPERATOR, GH_REAL, GH_READ, W3, Wtheta) & ! p3t + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: apply_mixed_wp_operator_code +end type + +!------------------------------------------------------------------------------- +! Contained functions/subroutines +!------------------------------------------------------------------------------- +public :: apply_mixed_wp_operator_code + +contains + +!> @brief Compute the LHS of the semi-implicit system +!> @param[in] cell Horizontal cell index +!> @param[in] nlayers Number of layers +!> @param[in,out] lhs_w Mixed operator applied to the vertical momentum equation +!> @param[in,out] lhs_p Mixed operator applied to the equation of state +!> @param[in] wind_uv Horizontal wind field +!> @param[in] wind_w Vertical wind field +!> @param[in] exner Exner pressure field +!> @param[in] ncell0 Total number of cells for the pt2 operator +!> @param[in] pt2 Projection operator from W2 to Wtheta +!> @param[in] mt_lumped_inv Lumped inverse mass matrix for the Wtheta space +!> @param[in] ncell1 Total number of cells for the mu_cd operator +!> @param[in] mu_cd Generalised mass matrix for the momentum equation +!> @param[in] ncell2 Total number of cells for the p2t operator +!> @param[in] p2t Generalised projection matrix from Wtheta to W2 +!> @param[in] ncell3 Total number of cells for the grad operator +!> @param[in] grad Generalised gradient operator for the momentum equation +!> @param[in] norm_u Normalisation field for the momentum equation +!> @param[in] ncell4 Total number of cells for the m3p operator +!> @param[in] m3p Weighted mass matrix for the W3 space +!> @param[in] ncell5 Total number of cells for the q32 operator +!> @param[in] q32 Projection operator from W2 to W3 +!> @param[in] ncell6 Total number of cells for the p3t operator +!> @param[in] p3t Projection operator from W2 to Wtheta +!> @param[in] ndf_w2v Number of degrees of freedom per cell for the vertical wind space +!> @param[in] undf_w2v Unique number of degrees of freedom for the vertical wind space +!> @param[in] map_w2v Dofmap for the cell at the base of the column for the vertical wind space +!> @param[in] ndf_w3 Norm_umber of degrees of freedom per cell for the pressure space +!> @param[in] ndf_w3 Unique number of degrees of freedom for the pressure space +!> @param[in] map_w3 Dofmap for the cell at the base of the column for the pressure space +!> @param[in] ndf_w2h Number of degrees of freedom per cell for the horizontal wind space +!> @param[in] undf_w2h Unique number of degrees of freedom for the horizontal wind space +!> @param[in] map_w2h Dofmap for the cell at the base of the column for the horizontal wind space +!> @param[in] undf_wt Number of degrees of freedom per cell for the potential +!! temperature space +!> @param[in] undf_wt Unique number of degrees of freedom for the potential +!! temperature space +!> @param[in] map_wt Dofmap for the cell at the base of the column for the +!! potential temperature space +!> @param[in] ndf_w2 Number of degrees of freedom per cell for the wind space +!> @param[in] undf_w2 Unique number of degrees of freedom for the wind space +!> @param[in] map_w2 Dofmap for the cell at the base of the column for the wind space +subroutine apply_mixed_wp_operator_code(cell, & + nlayers, & + lhs_w, & + lhs_p, & + wind_uv, wind_w, exner, & + ncell0, pt2, & + mt_lumped_inv, & + ncell1, mu_cd, & + ncell2, P2t, & + ncell3, grad, & + norm_u, & + ncell4, m3p, & + ncell5, q32, & + ncell6, p3t, & + ndf_w2v, undf_w2v, map_w2v, & + ndf_w3, undf_w3, map_w3, & + ndf_w2h, undf_w2h, map_w2h, & + ndf_wt, undf_wt, map_wt, & + ndf_w2, undf_w2, map_w2) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: cell, nlayers + integer(kind=i_def), intent(in) :: ncell0, ncell1, ncell2, ncell3 + integer(kind=i_def), intent(in) :: ncell4, ncell5, ncell6 + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + integer(kind=i_def), intent(in) :: undf_w2h, ndf_w2h + integer(kind=i_def), intent(in) :: undf_w2v, ndf_w2v + integer(kind=i_def), intent(in) :: undf_wt, ndf_wt + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w2h), intent(in) :: map_w2h + integer(kind=i_def), dimension(ndf_w2v), intent(in) :: map_w2v + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + integer(kind=i_def), dimension(ndf_wt), intent(in) :: map_wt + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + + ! Fields + real(kind=r_solver), dimension(undf_w2v), intent(inout) :: lhs_w + real(kind=r_solver), dimension(undf_w3), intent(inout) :: lhs_p + real(kind=r_solver), dimension(undf_w2h), intent(in) :: wind_uv + real(kind=r_solver), dimension(undf_w2v), intent(in) :: wind_w + real(kind=r_solver), dimension(undf_w2), intent(in) :: norm_u + real(kind=r_solver), dimension(undf_wt), intent(in) :: mt_lumped_inv + real(kind=r_solver), dimension(undf_w3), intent(in) :: exner + + ! Operators + real(kind=r_solver), dimension(ncell0, ndf_wt, ndf_w2), intent(in) :: pt2 + real(kind=r_solver), dimension(ncell1, ndf_w2, ndf_w2), intent(in) :: mu_cd + real(kind=r_solver), dimension(ncell2, ndf_w2, ndf_wt), intent(in) :: p2t + real(kind=r_solver), dimension(ncell3, ndf_w2, ndf_w3), intent(in) :: grad + real(kind=r_solver), dimension(ncell4, ndf_w3, ndf_w3), intent(in) :: m3p + real(kind=r_solver), dimension(ncell5, ndf_w3, ndf_w2), intent(in) :: q32 + real(kind=r_solver), dimension(ncell6, ndf_w3, ndf_wt), intent(in) :: p3t + + ! Internal variables + integer(kind=i_def) :: df, df2, ij, & + nm1, iw3, iwt, & + iw2, iw2h, iw2v + real(kind=r_solver), dimension(0:nlayers-1,ndf_w2) :: u_e + real(kind=r_solver), dimension(0:nlayers) :: t_col + + ! Set up some useful shorthands for indices + ij = (cell-1)*nlayers + 1 + nm1 = nlayers-1 + iw3 = map_w3(1) + iwt = map_wt(1) + + ! Create the element velocity field + do df = 1, ndf_w2h + iw2h = map_w2h(df) + u_e(:,df) = wind_uv(iw2h:iw2h+nm1) + end do + do df = 1, ndf_w2v + iw2v = map_w2v(df) + u_e(:,ndf_w2h+df) = wind_w(iw2v:iw2v+nm1) + end do + + ! Compute t for the column + t_col(:) = 0.0_r_solver + do df = 1, ndf_w2 + t_col(0:nm1) = t_col(0:nm1) - pt2(ij:ij+nm1, 1, df)*u_e(:,df) + t_col(1:nm1+1) = t_col(1:nm1+1) - pt2(ij:ij+nm1, 2, df)*u_e(:,df) + end do + t_col(:) = t_col(:) * mt_lumped_inv(iwt:iwt+1+nm1) + + ! LHS W + iw2v = map_w2v(1) + lhs_w(iw2v:iw2v+nlayers) = 0.0_r_solver + + do df = 1, ndf_w2v + iw2v = map_w2v(df) + iw2 = map_w2(ndf_w2h+df) + lhs_w(iw2v:iw2v+nm1) = lhs_w(iw2v:iw2v+nm1) & + + norm_u(iw2:iw2+nm1)*( & + - p2t(ij:ij+nm1, ndf_w2h+df, 1)*t_col(0:nm1) & + - p2t(ij:ij+nm1, ndf_w2h+df, 2)*t_col(1:nm1+1) & + - grad(ij:ij+nm1, ndf_w2h+df, 1)*exner(iw3:iw3+nm1)) + + end do + do df2 = 1, ndf_w2 + do df = 1, ndf_w2v + iw2v = map_w2v(df) + iw2 = map_w2(ndf_w2h+df) + lhs_w(iw2v:iw2v+nm1) = lhs_w(iw2v:iw2v+nm1) & + + norm_u(iw2:iw2+nm1)* & + mu_cd(ij:ij+nm1, ndf_w2h+df, df2)*u_e(:,df2) + + end do + end do + ! Set BC for lhs_w + lhs_w(map_w2v(1)) = 0.0_r_solver + lhs_w(map_w2v(2)+nlayers-1) = 0.0_r_solver + + ! LHS P + lhs_p(iw3:iw3+nm1) = m3p(ij:ij+nm1, 1, 1)*exner(iw3:iw3+nm1) & + - p3t(ij:ij+nm1, 1, 1)*t_col(0:nm1) & + - p3t(ij:ij+nm1, 1, 2)*t_col(1:nm1+1) + do df = 1, ndf_w2 + lhs_p(iw3:iw3+nm1) = lhs_p(iw3:iw3+nm1) + q32(ij:ij+nm1, 1, df)*u_e(:,df) + end do + +end subroutine apply_mixed_wp_operator_code + +end module apply_mixed_wp_operator_kernel_mod diff --git a/science/gungho/source/kernel/solver/eliminated_theta_q22_kernel_mod.F90 b/science/gungho/source/kernel/solver/eliminated_theta_q22_kernel_mod.F90 index acabd2c24..442002ce4 100644 --- a/science/gungho/source/kernel/solver/eliminated_theta_q22_kernel_mod.F90 +++ b/science/gungho/source/kernel/solver/eliminated_theta_q22_kernel_mod.F90 @@ -30,6 +30,10 @@ module eliminated_theta_q22_kernel_mod use fs_continuity_mod, only: W2, Wtheta, Wchi use kernel_mod, only: kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -176,8 +180,10 @@ subroutine eliminated_theta_q22_code(cell, nlayers, ncell_3d, & chi3_e(df) = chi3(map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, basis_chi, diff_basis_chi, jac, dj) + q22_op(ik, :, :) = 0.0_r_solver do qp2 = 1, nqp_v do qp1 = 1, nqp_h diff --git a/science/gungho/source/kernel/solver/project_eos_operators_kernel_mod.F90 b/science/gungho/source/kernel/solver/project_eos_operators_kernel_mod.F90 index e9714db8c..474f6064b 100644 --- a/science/gungho/source/kernel/solver/project_eos_operators_kernel_mod.F90 +++ b/science/gungho/source/kernel/solver/project_eos_operators_kernel_mod.F90 @@ -28,6 +28,10 @@ module project_eos_operators_kernel_mod use fs_continuity_mod, only: W3, Wtheta use kernel_mod, only: kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -201,7 +205,9 @@ subroutine project_eos_operators_code(cell, nlayers, & p3theta(ik,:,:) = 0.0_r_solver do qp2 = 1, nqp_v do qp1 = 1, nqp_h - call pointwise_coordinate_jacobian(ndf_chi, chi1_e, chi2_e, chi3_e, & + call pointwise_coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, chi1_e, chi2_e, chi3_e, & ipanel, rsol_basis_chi(:,:,qp1,qp2), & rsol_diff_basis_chi(:,:,qp1,qp2), & jac, dj ) diff --git a/science/gungho/source/kernel/solver/schur_backsub_kernel_mod.F90 b/science/gungho/source/kernel/solver/schur_backsub_kernel_mod.F90 index 84fd4ebcb..07d975356 100644 --- a/science/gungho/source/kernel/solver/schur_backsub_kernel_mod.F90 +++ b/science/gungho/source/kernel/solver/schur_backsub_kernel_mod.F90 @@ -28,14 +28,13 @@ module schur_backsub_kernel_mod ! Kernel metadata for PSyclone type, public, extends(kernel_type) :: schur_backsub_kernel_type private - type(arg_type) :: meta_args(9) = (/ & + type(arg_type) :: meta_args(8) = (/ & arg_type(GH_FIELD, GH_REAL, GH_INC, W2h), & ! lhs_h arg_type(GH_FIELD, GH_REAL, GH_WRITE, W2v), & ! lhs_v arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! rhs arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! exner_inc arg_type(GH_OPERATOR, GH_REAL, GH_READ, W2, W3), & ! div arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! norm - arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Hb_inv arg_type(GH_SCALAR, GH_LOGICAL, GH_READ), & ! lam arg_type(GH_FIELD, GH_REAL, GH_READ, W2) & ! mask /) @@ -90,7 +89,6 @@ subroutine schur_backsub_code(cell, & ncell_3d, & div, & norm, & - Hb_inv, & lam, mask, & ndfh, undfh, maph, & ndfv, undfv, mapv, & @@ -117,7 +115,6 @@ subroutine schur_backsub_code(cell, & real(kind=r_solver), dimension(undfv), intent(inout) :: lhs_v real(kind=r_solver), dimension(ncell_3d,ndf1,ndf2), intent(in) :: div real(kind=r_solver), dimension(undf1), intent(in) :: norm - real(kind=r_solver), dimension(undf1), intent(in) :: Hb_inv real(kind=r_solver), dimension(undf1), intent(in) :: rhs real(kind=r_solver), dimension(undf1), intent(in) :: mask @@ -131,10 +128,11 @@ subroutine schur_backsub_code(cell, & do df = 1, ndfh ih = maph(df) i1 = map1(df) + lhs_h(ih:ih+nl) = lhs_h(ih:ih+nl) + 0.5_r_solver*rhs(i1:i1+nl) do df2 = 1, ndf2 i2 = map2(df2) - lhs_h(ih:ih+nl) = lhs_h(ih:ih+nl) + 0.5_r_solver*rhs(i1:i1+nl) & - + div(ij:ij+nl, df, df2)*exner_inc(i2:i2+nl)*norm(i1:i1+nl)*Hb_inv(i1:i1+nl) + lhs_h(ih:ih+nl) = lhs_h(ih:ih+nl) & + + div(ij:ij+nl, df, df2)*exner_inc(i2:i2+nl)*norm(i1:i1+nl) end do end do @@ -149,7 +147,7 @@ subroutine schur_backsub_code(cell, & do df2 = 1, ndf2 i2 = map2(df2) lhs_v(iv:iv+nl) = lhs_v(iv:iv+nl) & - + div(ij:ij+nl, ndfh + df, df2)*exner_inc(i2:i2+nl)*norm(i1:i1+nl)*Hb_inv(i1:i1+nl) + + div(ij:ij+nl, ndfh + df, df2)*exner_inc(i2:i2+nl)*norm(i1:i1+nl) end do end do diff --git a/science/gungho/source/kernel/solver/w2_normalisation_kernel_mod.F90 b/science/gungho/source/kernel/solver/w2_normalisation_kernel_mod.F90 index 7116bbdb7..29ae1b64e 100644 --- a/science/gungho/source/kernel/solver/w2_normalisation_kernel_mod.F90 +++ b/science/gungho/source/kernel/solver/w2_normalisation_kernel_mod.F90 @@ -25,6 +25,10 @@ module w2_normalisation_kernel_mod use fs_continuity_mod, only : W2, Wchi use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -136,15 +140,19 @@ subroutine w2_normalisation_code(nlayers, & chi_2_cell(df) = chi_2(map_chi(df) + k) chi_3_cell(df) = chi_3(map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, & - ndf, & - chi_1_cell, & - chi_2_cell, & - chi_3_cell, & - ipanel, & - chi_basis, & + call coordinate_jacobian(coord_system, & + geometry, & + topology, & + scaled_radius, & + ndf_chi, & + ndf, & + chi_1_cell, & + chi_2_cell, & + chi_3_cell, & + ipanel, & + chi_basis, & chi_diff_basis, & - jacobian, & + jacobian, & dj) do df = 1,ndf JTJ = matmul(transpose(jacobian(:,:,df)),jacobian(:,:,df)) diff --git a/science/gungho/source/kernel/solver/weighted_m3_kernel_mod.F90 b/science/gungho/source/kernel/solver/weighted_m3_kernel_mod.F90 index cb8728598..8242d80db 100644 --- a/science/gungho/source/kernel/solver/weighted_m3_kernel_mod.F90 +++ b/science/gungho/source/kernel/solver/weighted_m3_kernel_mod.F90 @@ -21,6 +21,10 @@ module weighted_m3_kernel_mod use fs_continuity_mod, only: W3 use kernel_mod, only: kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -139,7 +143,8 @@ subroutine weighted_m3_code(cell, nlayers, ncell_3d, & chi2_e(df) = chi2(loc) chi3_e(df) = chi3(loc) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, basis_chi, diff_basis_chi, jac, dj) ik = 1 + k + (cell-1)*nlayers diff --git a/science/gungho/source/kernel/transport/common/vorticity_advection_kernel_mod.F90 b/science/gungho/source/kernel/transport/common/vorticity_advection_kernel_mod.F90 index cfb37ab12..6e882ff2b 100644 --- a/science/gungho/source/kernel/transport/common/vorticity_advection_kernel_mod.F90 +++ b/science/gungho/source/kernel/transport/common/vorticity_advection_kernel_mod.F90 @@ -34,6 +34,10 @@ module vorticity_advection_kernel_mod use fs_continuity_mod, only: W1, W2 use cross_product_mod, only: cross_product +use base_mesh_config_mod, only: geometry, topology +use finite_element_config_mod, only: coord_system +use planet_config_mod, only: scaled_radius + implicit none private @@ -177,8 +181,10 @@ subroutine vorticity_advection_code(nlayers, & vorticity_at_quad(:) = vorticity_at_quad(:) & + vorticity( map_w1(df) + k )*w1_basis(:,df,qp1,qp2) end do - call pointwise_coordinate_jacobian(ndf_chi, chi_1_e, chi_2_e, chi_3_e, & - ipanel, chi_basis(:,:,qp1,qp2), & + call pointwise_coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, chi_1_e, chi_2_e, chi_3_e, & + ipanel, chi_basis(:,:,qp1,qp2), & chi_diff_basis(:,:,qp1,qp2), jac, dj) jac_inv = pointwise_coordinate_jacobian_inverse(jac, dj) jac = matmul(jac_inv,transpose(jac_inv)) diff --git a/science/gungho/source/kernel/transport/common/w2_vorticity_advection_kernel_mod.F90 b/science/gungho/source/kernel/transport/common/w2_vorticity_advection_kernel_mod.F90 index f9bfb5db2..01d08c0d8 100644 --- a/science/gungho/source/kernel/transport/common/w2_vorticity_advection_kernel_mod.F90 +++ b/science/gungho/source/kernel/transport/common/w2_vorticity_advection_kernel_mod.F90 @@ -32,6 +32,10 @@ module w2_vorticity_advection_kernel_mod use fs_continuity_mod, only : W2 use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -152,7 +156,8 @@ subroutine w2_vorticity_advection_code(nlayers, & chi_2_e(df) = chi_2( loc ) chi_3_e(df) = chi_3( loc ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) do df = 1, ndf_w2 diff --git a/science/gungho/unit-test/kernel/core_dynamics/assemble_w2h_from_w2hb_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/assemble_w2h_from_w2hb_kernel_mod_test.pf new file mode 100644 index 000000000..351b39ba5 --- /dev/null +++ b/science/gungho/unit-test/kernel/core_dynamics/assemble_w2h_from_w2hb_kernel_mod_test.pf @@ -0,0 +1,86 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright Met Office. All rights reserved. +! For further details please refer to the file COPYRIGHT.txt +! which you should have received as part of this distribution. +!----------------------------------------------------------------------------- + +!> Test the assembly of a W2h field from a W2hb field +!> +module assemble_w2h_from_w2hb_kernel_mod_test + + use constants_mod, only : i_def, r_solver + use funit + + implicit none + + private + public :: test_all + +contains + + @Test + subroutine test_all( ) + + use assemble_w2h_from_w2hb_kernel_mod, only: assemble_w2h_from_w2hb_code + + implicit none + + real(r_solver), parameter :: tol = 1.0e-6_r_solver + + integer(i_def), parameter :: ncells = 2 + integer(i_def), parameter :: nlayers = 1 + integer(i_def), parameter :: ndf_w2h = 2 + integer(i_def), parameter :: undf_w2h = ndf_w2h*nlayers + integer(i_def), parameter :: ndf_w2hb = 2 + integer(i_def), parameter :: undf_w2hb = ndf_w2hb*nlayers*ncells + + integer(i_def), dimension( ndf_w2h, ncells ) :: map_w2h + integer(i_def), dimension( ndf_w2hb, ncells ) :: map_w2hb + + real(r_solver), dimension( undf_w2h ) :: field_w2h + real(r_solver), dimension( undf_w2hb ) :: field_w2hb + real(r_solver), dimension( undf_w2h ) :: answer + + integer(i_def) :: cell + + ! Assume a biperiodic mesh with two cells + ! Locations of W2 dofs + ! |---|---| + ! 1 2 1 + ! |---|---| + map_w2h(:,1) = (/ 1, nlayers+1 /) + map_w2h(:,2) = (/ nlayers+1, 1 /) + ! + ! Locations of W2b dofs + ! |---|---| + ! |1 2|3 4| + ! |---|---| + map_w2hb(:,1) = (/ 1, nlayers+1 /) + map_w2hb(:,2) = (/ 2*nlayers+1, 3*nlayers+1 /) + + field_w2h = (/ 3.0_r_solver, 4.0_r_solver /) + + field_w2hb = (/ 1.0_r_solver, 2.0_r_solver, 3.0_r_solver, 4.0_r_solver /) + + do cell = 1, ncells + call assemble_w2h_from_w2hb_code( nlayers, & + field_w2h, & + field_w2hb, & + ndf_w2h, & + undf_w2h, & + map_w2h(:,cell), & + ndf_w2hb, & + undf_w2hb, & + map_w2hb(:,cell) & + ) + end do + + ! field_w2h should equal it's initial value plus the two + ! adjacent w2hb values + answer = (/ 8.0_r_solver, 9.0_r_solver /) + + @assertEqual(answer, field_w2h, tol) + + end subroutine test_all + +end module assemble_w2h_from_w2hb_kernel_mod_test diff --git a/science/gungho/unit-test/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod_test.pf index 658e676fd..5f714217c 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/compute_coriolis_matrix_kernel_mod_test.pf @@ -95,7 +95,7 @@ contains horizontal_transport_predictor=.false., & vector_invariant=.true.) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/core_dynamics/compute_dl_matrix_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/compute_dl_matrix_kernel_mod_test.pf index 348fb1efa..89caacaa2 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/compute_dl_matrix_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/compute_dl_matrix_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module compute_dl_matrix_kernel_mod_test - use constants_mod, only : i_def, r_def, r_second + use constants_mod, only : i_def, r_def, r_second, imdi use damping_layer_config_mod, only : dl_base, dl_str, dl_type, dl_type_standard use get_unit_test_m3x3_dofmap_mod, & only : get_w0_m3x3_dofmap, get_w3_m3x3_dofmap @@ -67,7 +67,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod_test.pf index dc3e55e0d..4077a2386 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/compute_vert_coriolis_matrix_kernel_mod_test.pf @@ -121,7 +121,7 @@ contains scaling_factor=1.0_r_def & ) - call init_chi_transforms() + call init_chi_transforms(geometry_spherical, topology_non_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod_test.pf index aa9b4b51b..893437da3 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/kinetic_energy_gradient_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module kinetic_energy_gradient_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, imdi use get_unit_test_m3x3_q3x3x3_sizes_mod, only : get_w0_m3x3_q3x3x3_size, & get_w2_m3x3_q3x3x3_size, & @@ -92,7 +92,7 @@ contains horizontal_transport_predictor=.false., & vector_invariant=.false.) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/core_dynamics/project_eos_pressure_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/project_eos_pressure_kernel_mod_test.pf index 7dbe255e1..2f78ebc87 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/project_eos_pressure_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/project_eos_pressure_kernel_mod_test.pf @@ -89,7 +89,7 @@ contains p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic ) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/core_dynamics/project_eos_rho_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/project_eos_rho_kernel_mod_test.pf index f08a05fd7..2edd683f7 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/project_eos_rho_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/project_eos_rho_kernel_mod_test.pf @@ -92,7 +92,7 @@ contains profile_data=profile_data, & profile_heights=profile_heights ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/core_dynamics/rhs_project_eos_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/rhs_project_eos_kernel_mod_test.pf index 47193101b..6b83c0dc1 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/rhs_project_eos_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/rhs_project_eos_kernel_mod_test.pf @@ -92,7 +92,7 @@ contains profile_data=profile_data, & profile_heights=profile_heights ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/core_dynamics/vorticity_rhs_kernel_mod_test.pf b/science/gungho/unit-test/kernel/core_dynamics/vorticity_rhs_kernel_mod_test.pf index f5751b76d..99f563c5f 100644 --- a/science/gungho/unit-test/kernel/core_dynamics/vorticity_rhs_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/core_dynamics/vorticity_rhs_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module vorticity_rhs_kernel_mod_test - use constants_mod, only: i_def, r_def + use constants_mod, only: i_def, r_def, imdi use funit implicit none @@ -48,7 +48,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/diagnostics/compute_energetics_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diagnostics/compute_energetics_kernel_mod_test.pf index e9e92bf81..01ca7143b 100644 --- a/science/gungho/unit-test/kernel/diagnostics/compute_energetics_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diagnostics/compute_energetics_kernel_mod_test.pf @@ -9,7 +9,8 @@ !> module compute_energetics_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only: i_def, r_def, imdi + use driver_water_constants_mod, only : Lv => latent_heat_h2o_condensation, & Lf => latent_heat_h2o_fusion use get_unit_test_m3x3_q3x3x3_sizes_mod, only : get_w0_m3x3_q3x3x3_size, & @@ -74,7 +75,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/diagnostics/compute_entropy_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diagnostics/compute_entropy_kernel_mod_test.pf index 6e4dd39b0..14fe4aaa5 100644 --- a/science/gungho/unit-test/kernel/diagnostics/compute_entropy_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diagnostics/compute_entropy_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module compute_entropy_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, imdi use get_unit_test_m3x3_q3x3x3_sizes_mod, only : get_w0_m3x3_q3x3x3_size, & get_wtheta_m3x3_q3x3x3_size, & get_w3_m3x3_q3x3x3_size @@ -63,7 +63,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/diagnostics/compute_moist_mass_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diagnostics/compute_moist_mass_kernel_mod_test.pf index 63133246b..e28bc3ac1 100644 --- a/science/gungho/unit-test/kernel/diagnostics/compute_moist_mass_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diagnostics/compute_moist_mass_kernel_mod_test.pf @@ -7,7 +7,7 @@ !> module compute_moist_mass_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, imdi use get_unit_test_m3x3_q3x3x3_sizes_mod, only : get_w0_m3x3_q3x3x3_size, & get_w3_m3x3_q3x3x3_size, & get_wtheta_m3x3_q3x3x3_size @@ -67,7 +67,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/diagnostics/compute_total_aam_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diagnostics/compute_total_aam_kernel_mod_test.pf index 851d06ebc..98546499b 100644 --- a/science/gungho/unit-test/kernel/diagnostics/compute_total_aam_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diagnostics/compute_total_aam_kernel_mod_test.pf @@ -82,7 +82,7 @@ contains p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_spherical, topology_fully_periodic) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/diagnostics/compute_total_pv_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diagnostics/compute_total_pv_kernel_mod_test.pf index 4eae5a9be..6c6c69042 100644 --- a/science/gungho/unit-test/kernel/diagnostics/compute_total_pv_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diagnostics/compute_total_pv_kernel_mod_test.pf @@ -86,7 +86,8 @@ contains rd=300.0_r_def, cp=1000.0_r_def, & p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + + call init_chi_transforms(geometry_spherical, topology_fully_periodic) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/diffusion/momentum_viscosity_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diffusion/momentum_viscosity_kernel_mod_test.pf index 31f0bb9cf..97e43707c 100644 --- a/science/gungho/unit-test/kernel/diffusion/momentum_viscosity_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diffusion/momentum_viscosity_kernel_mod_test.pf @@ -6,7 +6,7 @@ module momentum_viscosity_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, imdi use get_unit_test_m3x3_q3x3x3_sizes_mod, only : get_w2_m3x3_q3x3x3_size use get_unit_test_m3x3_dofmap_mod, only : get_w2_m3x3_dofmap, & @@ -51,7 +51,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/diffusion/tracer_smagorinsky_diff_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diffusion/tracer_smagorinsky_diff_kernel_mod_test.pf index 604ca9319..445276032 100644 --- a/science/gungho/unit-test/kernel/diffusion/tracer_smagorinsky_diff_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diffusion/tracer_smagorinsky_diff_kernel_mod_test.pf @@ -6,7 +6,7 @@ module tracer_smagorinsky_diff_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, imdi use get_unit_test_m3x3_q3x3x3_sizes_mod, only : get_w2_m3x3_q3x3x3_size, & get_wtheta_m3x3_q3x3x3_size use get_unit_test_m3x3_dofmap_mod, only : get_w2_m3x3_dofmap, & @@ -64,7 +64,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/diffusion/tracer_viscosity_kernel_mod_test.pf b/science/gungho/unit-test/kernel/diffusion/tracer_viscosity_kernel_mod_test.pf index 495c48dff..284c7ca79 100644 --- a/science/gungho/unit-test/kernel/diffusion/tracer_viscosity_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/diffusion/tracer_viscosity_kernel_mod_test.pf @@ -6,7 +6,7 @@ module tracer_viscosity_kernel_mod_test - use constants_mod, only: i_def, r_def + use constants_mod, only: i_def, r_def, imdi use funit implicit none @@ -47,7 +47,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/external_forcing/deep_hot_jupiter_kernel_mod_test.pf b/science/gungho/unit-test/kernel/external_forcing/deep_hot_jupiter_kernel_mod_test.pf index 00640b1af..3f914a2a0 100644 --- a/science/gungho/unit-test/kernel/external_forcing/deep_hot_jupiter_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/external_forcing/deep_hot_jupiter_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module deep_hot_jupiter_kernel_mod_test - use constants_mod, only : i_def, r_def, r_second, PI + use constants_mod, only : i_def, r_def, r_second, PI, imdi use coord_transform_mod, only : llr2xyz use funit @@ -70,7 +70,7 @@ contains runge_kutta_method=runge_kutta_method_ssp3, & spinup_period=0.0_r_second, spinup_alpha=.false.) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/external_forcing/earth_like_kernel_mod_test.pf b/science/gungho/unit-test/kernel/external_forcing/earth_like_kernel_mod_test.pf index 17e485b6b..27f8410de 100644 --- a/science/gungho/unit-test/kernel/external_forcing/earth_like_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/external_forcing/earth_like_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module earth_like_kernel_mod_test - use constants_mod, only : i_def, r_def, r_second, PI + use constants_mod, only : i_def, r_def, r_second, PI, imdi use coord_transform_mod, only : llr2xyz use funit @@ -76,7 +76,7 @@ contains runge_kutta_method=runge_kutta_method_ssp3, & spinup_period=0.0_r_second, spinup_alpha=.false.) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine set_up @@ -99,7 +99,6 @@ contains @test subroutine test_all() -use planet_config_mod, only : scaled_radius use, intrinsic :: iso_fortran_env, only : real64 use earth_like_kernel_mod, only : earth_like_code diff --git a/science/gungho/unit-test/kernel/external_forcing/held_suarez_kernel_mod_test.pf b/science/gungho/unit-test/kernel/external_forcing/held_suarez_kernel_mod_test.pf index d1e1f11e9..18f0dc4a9 100644 --- a/science/gungho/unit-test/kernel/external_forcing/held_suarez_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/external_forcing/held_suarez_kernel_mod_test.pf @@ -8,8 +8,8 @@ !> module held_suarez_kernel_mod_test - use constants_mod, only : i_def, r_def, r_second, PI - use coord_transform_mod, only : llr2xyz + use constants_mod, only: i_def, r_def, r_second, PI, imdi + use coord_transform_mod, only: llr2xyz use funit implicit none @@ -72,7 +72,7 @@ contains runge_kutta_method=runge_kutta_method_ssp3, & spinup_period=0.0_r_second, spinup_alpha=.false.) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/external_forcing/shallow_hot_jupiter_kernel_mod_test.pf b/science/gungho/unit-test/kernel/external_forcing/shallow_hot_jupiter_kernel_mod_test.pf index 854255e9c..47351ab00 100644 --- a/science/gungho/unit-test/kernel/external_forcing/shallow_hot_jupiter_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/external_forcing/shallow_hot_jupiter_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module shallow_hot_jupiter_kernel_mod_test - use constants_mod, only : i_def, r_def, r_second, PI + use constants_mod, only : i_def, r_def, r_second, PI, imdi use coord_transform_mod, only : llr2xyz use funit @@ -71,7 +71,7 @@ contains runge_kutta_method=runge_kutta_method_ssp3, & spinup_period=0.0_r_second, spinup_alpha=.false.) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/external_forcing/tidally_locked_earth_kernel_mod_test.pf b/science/gungho/unit-test/kernel/external_forcing/tidally_locked_earth_kernel_mod_test.pf index 5971150fe..633c748c6 100644 --- a/science/gungho/unit-test/kernel/external_forcing/tidally_locked_earth_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/external_forcing/tidally_locked_earth_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module tidally_locked_earth_kernel_mod_test - use constants_mod, only : i_def, r_def, r_second, PI + use constants_mod, only : i_def, r_def, r_second, PI, imdi use coord_transform_mod, only : llr2xyz use funit @@ -17,11 +17,13 @@ module tidally_locked_earth_kernel_mod_test private public :: set_up, tear_down, test_all - real(kind=r_def), parameter :: rd = 287.05_r_def - real(kind=r_def), parameter :: cp = 1005.0_r_def - real(kind=r_def), parameter :: kappa = rd/cp - real(kind=r_def), parameter :: dlat = 1.0_r_def, dlon = 1.0_r_def, dz = 10000.0_r_def - real(kind=r_def), parameter :: dt = 1800.0_r_def + real(kind=r_def), parameter :: rd = 287.05_r_def + real(kind=r_def), parameter :: cp = 1005.0_r_def + real(kind=r_def), parameter :: kappa = rd/cp + real(kind=r_def), parameter :: dlat = 1.0_r_def + real(kind=r_def), parameter :: dlon = 1.0_r_def + real(kind=r_def), parameter :: dz = 10000.0_r_def + real(kind=r_def), parameter :: dt = 1800.0_r_def contains @@ -70,7 +72,7 @@ contains runge_kutta_method=runge_kutta_method_ssp3, & spinup_period=0.0_r_second, spinup_alpha=.false.) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/initialisation/hydrostatic_exner_kernel_mod_test.pf b/science/gungho/unit-test/kernel/initialisation/hydrostatic_exner_kernel_mod_test.pf index e91b2770c..49fa9d49d 100644 --- a/science/gungho/unit-test/kernel/initialisation/hydrostatic_exner_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/initialisation/hydrostatic_exner_kernel_mod_test.pf @@ -148,7 +148,7 @@ contains perturb_init=.false., perturb_magnitude=0, & perturb_seed=0 ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) nlayers=3 call get_w0_m3x3_q3x3x3_size( this%ndf_w0, this%undf_w0, ncells, & diff --git a/science/gungho/unit-test/kernel/initialisation/initial_rho_sample_kernel_mod_test.pf b/science/gungho/unit-test/kernel/initialisation/initial_rho_sample_kernel_mod_test.pf index 4c2b182e8..97b55e828 100644 --- a/science/gungho/unit-test/kernel/initialisation/initial_rho_sample_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/initialisation/initial_rho_sample_kernel_mod_test.pf @@ -82,7 +82,7 @@ contains perturb_init=.false., perturb_magnitude=0, & perturb_seed=0 ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/initialisation/initial_u_kernel_mod_test.pf b/science/gungho/unit-test/kernel/initialisation/initial_u_kernel_mod_test.pf index 4ff877458..04cd2be1f 100644 --- a/science/gungho/unit-test/kernel/initialisation/initial_u_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/initialisation/initial_u_kernel_mod_test.pf @@ -114,7 +114,7 @@ contains wavelength=wavelength, & wind_time_period=wind_time_period ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/initialisation/set_rho_kernel_mod_test.pf b/science/gungho/unit-test/kernel/initialisation/set_rho_kernel_mod_test.pf index dac91d1a6..610728b04 100644 --- a/science/gungho/unit-test/kernel/initialisation/set_rho_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/initialisation/set_rho_kernel_mod_test.pf @@ -132,7 +132,7 @@ contains p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/solver/apply_mixed_u_operator_kernel_mod_test.pf b/science/gungho/unit-test/kernel/solver/apply_mixed_u_operator_kernel_mod_test.pf new file mode 100644 index 000000000..111b48817 --- /dev/null +++ b/science/gungho/unit-test/kernel/solver/apply_mixed_u_operator_kernel_mod_test.pf @@ -0,0 +1,101 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright Met Office. All rights reserved. +! For further details please refer to the file COPYRIGHT.txt +! which you should have received as part of this distribution. +!----------------------------------------------------------------------------- + +!> Test the mixed operator of the semi-implicit lhs +module apply_mixed_u_operator_kernel_mod_test + + use constants_mod, only : i_def, r_solver + use funit + + implicit none + + private + public :: test_all + +contains + + @test( ) + subroutine test_all( ) + + use apply_mixed_u_operator_kernel_mod, only : apply_mixed_u_operator_code + + implicit none + + real(r_solver), parameter :: tol = 1.0e-6_r_solver + + ! Mesh + integer(i_def), parameter :: nlayers = 1 + integer(i_def), parameter :: cell = 1 + integer(i_def), parameter :: ncell = 1 + + ! Spaces + integer(i_def), parameter :: ndf_w2h = 2 + integer(i_def), parameter :: ndf_w2v = 2 + integer(i_def), parameter :: ndf_w2 = ndf_w2h+ndf_w2v + integer(i_def), parameter :: ndf_w3 = 1 + integer(i_def), parameter :: undf_w2h = ndf_w2h*nlayers + integer(i_def), parameter :: undf_w2v = nlayers + 1 + integer(i_def), parameter :: undf_w2 = undf_w2h + undf_w2v + integer(i_def), parameter :: undf_w3 = ndf_w3*nlayers + + ! Maps + integer(i_def), dimension(ndf_w2h) :: map_w2h + integer(i_def), dimension(ndf_w2v) :: map_w2v + integer(i_def), dimension(ndf_w2) :: map_w2 + integer(i_def), dimension(ndf_w3) :: map_w3 + + ! Operators + real(r_solver), dimension(ndf_w2, ndf_w2, ncell) :: Mu + real(r_solver), dimension(ndf_w2, ndf_w3, ncell) :: Grad + + ! Fields + real(r_solver), dimension(undf_w2) :: Nu, u + real(r_solver), dimension(undf_w2h) :: Luv, uv + real(r_solver), dimension(undf_w2v) :: w + real(r_solver), dimension(undf_w3) :: p + + integer(i_def) :: df + real(r_solver) :: answer + + map_w2h = (/ 1_i_def, 1_i_def + nlayers /) + map_w2v = (/ 1_i_def, 2_i_def /) + map_w2 = (/ 1_i_def, 1_i_def + nlayers, 1_i_def + 2*nlayers, 2_i_def + 2*nlayers /) + map_w3 = (/ 1_i_def /) + + ! Set up operators + Mu = 0.0_r_solver + do df = 1,ndf_w2 + Mu(df,df,1) = real(df,r_solver) + Grad(df,1,1) = (-1.0_r_solver)**df + end do + + ! Set up the fields + uv = (/ 0.0_r_solver, 1.0_r_solver /) + w = (/ 3.0_r_solver, -2.0_r_solver /) + p = (/ 1.2_r_solver /) + Nu = 2.0_r_solver + Luv = 0.0_r_solver + + ! Compute: (L_uv) = Nu*(Mu*u - Grad*p) + call apply_mixed_u_operator_code(cell, & + nlayers, & + Luv, & + uv, w, p, & + ncell, Mu, & + ncell, Grad, & + Nu, & + ndf_w2h, undf_w2h, map_w2h, & + ndf_w2h, undf_w2h, map_w2h, & + ndf_w2v, undf_w2v, map_w2v, & + ndf_w3, undf_w3, map_w3, & + ndf_w2, undf_w2, map_w2) + + @assertEqual(2.4_r_solver, Luv(1), tol) + @assertEqual(1.6_r_solver, Luv(2), tol) + + end subroutine test_all + +end module apply_mixed_u_operator_kernel_mod_test diff --git a/science/gungho/unit-test/kernel/solver/apply_mixed_wp_operator_kernel_mod_test.pf b/science/gungho/unit-test/kernel/solver/apply_mixed_wp_operator_kernel_mod_test.pf new file mode 100644 index 000000000..a95cbbd6f --- /dev/null +++ b/science/gungho/unit-test/kernel/solver/apply_mixed_wp_operator_kernel_mod_test.pf @@ -0,0 +1,160 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright Met Office. All rights reserved. +! For further details please refer to the file COPYRIGHT.txt +! which you should have received as part of this distribution. +!----------------------------------------------------------------------------- + +!> Test the mixed operator of the semi-implicit lhs +module apply_mixed_wp_operator_kernel_mod_test + + use constants_mod, only : i_def, r_solver + use funit + + implicit none + + private + public :: test_all + +contains + + @test( ) + subroutine test_all( ) + + use apply_mixed_wp_operator_kernel_mod, only : apply_mixed_wp_operator_code + + implicit none + + real(r_solver), parameter :: tol = 1.0e-6_r_solver + + ! Mesh + integer(i_def), parameter :: nlayers = 3 + integer(i_def), parameter :: cell = 1 + integer(i_def), parameter :: ncell = nlayers + + ! Spaces + integer(i_def), parameter :: ndf_w2h = 2 + integer(i_def), parameter :: ndf_w2v = 2 + integer(i_def), parameter :: ndf_w2 = ndf_w2h+ndf_w2v + integer(i_def), parameter :: ndf_wt = 2 + integer(i_def), parameter :: ndf_w3 = 1 + integer(i_def), parameter :: undf_w2h = ndf_w2h*nlayers + integer(i_def), parameter :: undf_w2v = nlayers + 1 + integer(i_def), parameter :: undf_w2 = undf_w2h + undf_w2v + integer(i_def), parameter :: undf_wt = nlayers + 1 + integer(i_def), parameter :: undf_w3 = ndf_w3*nlayers + + ! Maps + integer(i_def), dimension(ndf_w2h) :: map_w2h + integer(i_def), dimension(ndf_w2v) :: map_w2v + integer(i_def), dimension(ndf_w2) :: map_w2 + integer(i_def), dimension(ndf_wt) :: map_wt + integer(i_def), dimension(ndf_w3) :: map_w3 + + ! Operators + real(r_solver), dimension(ncell, ndf_w2, ndf_w2) :: Mu + real(r_solver), dimension(ncell, ndf_w2, ndf_wt) :: P2t + real(r_solver), dimension(ncell, ndf_w2, ndf_w3) :: Grad + real(r_solver), dimension(ncell, ndf_wt, ndf_w2) :: Pt2 + real(r_solver), dimension(ncell, ndf_w3, ndf_w3) :: M3p + real(r_solver), dimension(ncell, ndf_w3, ndf_wt) :: P3t + real(r_solver), dimension(ncell, ndf_w3, ndf_w2) :: Q32 + + ! Fields + real(r_solver), dimension(undf_w2) :: Nu + real(r_solver), dimension(undf_w2h) :: uv + real(r_solver), dimension(undf_w2v) :: Lw, w + real(r_solver), dimension(undf_wt) :: invMt + real(r_solver), dimension(undf_w3) :: p, Lp + + integer(i_def) :: df, k + real(r_solver), dimension(undf_w2v) :: answer + real(r_solver) :: answer_p + + map_w2h = (/ 1_i_def, 1_i_def + nlayers /) + map_w2v = (/ 1_i_def, 2_i_def /) + map_w2 = (/ 1_i_def, 1_i_def + nlayers, 1_i_def + 2*nlayers, 2_i_def + 2*nlayers /) + map_wt = (/ 1_i_def, 2_i_def /) + map_w3 = (/ 1_i_def /) + + ! Set up operators + Mu = 0.0_r_solver + + do df = 1,ndf_w2 + Mu(:,df,df) = real(df,r_solver) + Grad(:,df,1) = (-1.0_r_solver)**df + end do + + P2t(:,:,:) = 0.0_r_solver + P2t(:,3:4,:) = 0.5_r_solver + Pt2 = 0.0_r_solver + Pt2(:,1,3) = 7.0_r_solver + Pt2(:,2,4) = 9.0_r_solver + M3p = 0.5_r_solver + Q32 = 3.0_r_solver + P3t = 5.0_r_solver + + ! Set up the fields + do k = 1, nlayers + uv(k) = 0.0_r_solver + uv(k+nlayers) = 1.0_r_solver + end do + w = (/0.0_r_solver, 3.0_r_solver, -2.0_r_solver, 0.0_r_solver /) + p(:) = 1.2_r_solver + Nu(:) = 2.0_r_solver + invMt(:) = 0.25_r_solver + + ! Compute: (L_uv, L_w) = Nu*(Mu*u - Proj*t - Grad*p) + ! L_p = M3p*p - P3t*t + Q32*u + ! with t = -Mt^-1 * Pt2*u + call apply_mixed_wp_operator_code(cell, & + nlayers, & + Lw, Lp, & + uv, w, p, & + ncell, Pt2, & + invMt, & + ncell, Mu, & + ncell, P2t, & + ncell, Grad, & + Nu, & + ncell, M3p, & + ncell, Q32, & + ncell, P3t, & + ndf_w2v, undf_w2v, map_w2v, & + ndf_w3, undf_w3, map_w3, & + ndf_w2h, undf_w2h, map_w2h, & + ndf_wt, undf_wt, map_wt, & + ndf_w2, undf_w2, map_w2) + + ! The code below can be used to generate the answers required and + ! is kept to here to make altering the unit test following changes in the + ! kernel easier + !t(:) = 0.0_r_solver + !do k = 1, nlayers + ! t(k) = t(k) - Pt2(k,1,3)*w(k) - Pt2(k,1,4)*w(k+1) + ! t(k+1) = t(k+1) - Pt2(k,2,3)*w(k) - Pt2(k,2,4)*w(k+1) + !end do + !t(:) = invMt(:)*t(:) + + !answer(:) = 0.0_r_solver + !do k = 0, nlayers - 1 + ! do dfv = 1,ndf_w2v + ! u = (/ uv(1+k), uv(4+k), w(1+k), w(2+k) /) + ! df = ndf_w2h+dfv + ! answer(map_w2v(dfv)+k) = answer(map_w2v(dfv)+k) & + ! + Nu(map_w2(df)+k)*(sum(Mu(k+1,df,:)*u) & + ! - sum(P2t(k+1,df,:)*t(k+1:k+2)) & + ! - Grad(k+1,df,1)*p(1+k)) + ! end do + !end do + !u = (/ uv(1), uv(4), w(1), w(2) /) + !answer_p = M3p(1,1,1)*p(1) - sum(P3t(1,1,:)*t(1:2)) + sum(Q32(1,1,:)*u(1:4)) + + answer = (/ 0.0_r_solver, 58.0_r_solver, -32.0_r_solver, 0.0_r_solver /) + @assertEqual(answer, Lw, tol) + + answer_p = 72.6_r_solver + @assertEqual(answer_p, Lp(1), tol) + + end subroutine test_all + +end module apply_mixed_wp_operator_kernel_mod_test diff --git a/science/gungho/unit-test/kernel/solver/eliminated_theta_q22_kernel_mod_test.pf b/science/gungho/unit-test/kernel/solver/eliminated_theta_q22_kernel_mod_test.pf index 96a0b0d16..2e63c84cb 100644 --- a/science/gungho/unit-test/kernel/solver/eliminated_theta_q22_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/solver/eliminated_theta_q22_kernel_mod_test.pf @@ -8,7 +8,7 @@ module eliminated_theta_q22_kernel_mod_test use, intrinsic :: iso_fortran_env, only : real64 - use constants_mod, only : i_def, r_def, r_solver + use constants_mod, only : i_def, r_def, r_solver, imdi use funit implicit none @@ -48,7 +48,7 @@ contains coord_system=coord_system_xyz, & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/solver/project_eos_operators_kernel_mod_test.pf b/science/gungho/unit-test/kernel/solver/project_eos_operators_kernel_mod_test.pf index 4537740b9..38f8a35af 100644 --- a/science/gungho/unit-test/kernel/solver/project_eos_operators_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/solver/project_eos_operators_kernel_mod_test.pf @@ -95,7 +95,7 @@ contains rd=rd, cp=cp, p_zero=p_zero, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/science/gungho/unit-test/kernel/solver/schur_backsub_kernel_mod_test.pf b/science/gungho/unit-test/kernel/solver/schur_backsub_kernel_mod_test.pf index fcbb75093..0b5014e38 100644 --- a/science/gungho/unit-test/kernel/solver/schur_backsub_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/solver/schur_backsub_kernel_mod_test.pf @@ -23,7 +23,7 @@ contains implicit none - real(r_solver), parameter :: tol = 1.0e-12_r_solver + real(r_solver), parameter :: tol = 1.0e-6_r_solver ! Mesh integer(i_def), parameter :: nlayers = 1_i_def @@ -50,7 +50,7 @@ contains real(r_solver), dimension(ncell, ndf_w2, ndf_w3) :: Grad ! Fields - real(r_solver), dimension(undf_w2) :: rhs, mask, z, y + real(r_solver), dimension(undf_w2) :: rhs, mask, y real(r_solver), dimension(undf_w2h) :: Luv real(r_solver), dimension(undf_w2v) :: Lw real(r_solver), dimension(undf_w3) :: x @@ -58,8 +58,8 @@ contains ! Logicals logical(l_def), parameter :: lam = .true. - integer(i_def) :: df - real(r_solver) :: answer + integer(i_def) :: df + real(r_solver), dimension(undf_w2h) :: answer map_w2h = (/ 1_i_def, 1_i_def + nlayers /) map_w2v = (/ 1_i_def, 2_i_def /) @@ -73,7 +73,6 @@ contains ! Set up the fields y = (/ 0.0_r_solver, 1.0_r_solver, 3.0_r_solver, -2.0_r_solver /) - z = (/ 2.4_r_solver, 0.4_r_solver, 7.3_r_solver, 1.2_r_solver /) x = (/ 1.2_r_solver /) rhs = (/ 6.3_r_solver, 6.7_r_solver, 4.2_r_solver, 7.5_r_solver /) Luv = 0.0_r_solver @@ -87,22 +86,17 @@ contains ncell, & Grad, & y, & - z, & lam, mask, & ndf_w2h, undf_w2h, map_w2h, & ndf_w2v, undf_w2v, map_w2v, & ndf_w2, undf_w2, map_w2, & ndf_w3, undf_w3, map_w3 ) - do df = 1, ndf_w2h - answer = mask(df)*( 0.5_r_solver*rhs(df) + y(df)*z(df)*grad(1,df,1)*x(1)) - @assertEqual(answer, Luv(df), tol) - end do + answer = (/ 6.3_r_solver, 4.55_r_solver /) + @assertEqual(answer, Luv, tol) - do df = 1, ndf_w2v - answer = 0.0_r_solver - @assertEqual(answer, Lw(df), tol) - end do + answer = (/ 0.0_r_solver, 0.0_r_solver /) + @assertEqual(answer, Lw, tol) end subroutine test_all diff --git a/science/gungho/unit-test/kernel/solver/weighted_m3_kernel_mod_test.pf b/science/gungho/unit-test/kernel/solver/weighted_m3_kernel_mod_test.pf index e23ec3575..4e9d66796 100644 --- a/science/gungho/unit-test/kernel/solver/weighted_m3_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/solver/weighted_m3_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module weighted_m3_kernel_mod_test - use constants_mod, only: i_def, r_def + use constants_mod, only: i_def, r_def, imdi use funit implicit none @@ -48,7 +48,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/common/panel_edge_coords_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/common/panel_edge_coords_kernel_mod_test.pf index e85a0bc8a..e960987cc 100644 --- a/science/gungho/unit-test/kernel/transport/common/panel_edge_coords_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/common/panel_edge_coords_kernel_mod_test.pf @@ -80,7 +80,7 @@ contains vorticity_in_w1=.false. & ) - call init_chi_transforms() + call init_chi_transforms(geometry_spherical, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/common/panel_edge_weights_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/common/panel_edge_weights_kernel_mod_test.pf index bd34c90e1..5a23a3bea 100644 --- a/science/gungho/unit-test/kernel/transport/common/panel_edge_weights_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/common/panel_edge_weights_kernel_mod_test.pf @@ -80,7 +80,7 @@ contains vorticity_in_w1=.false. & ) - call init_chi_transforms() + call init_chi_transforms(geometry_spherical, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/common/transport_metadata_collection_test.pf b/science/gungho/unit-test/kernel/transport/common/transport_metadata_collection_test.pf index b1fb53e42..bb2dbf1ca 100644 --- a/science/gungho/unit-test/kernel/transport/common/transport_metadata_collection_test.pf +++ b/science/gungho/unit-test/kernel/transport/common/transport_metadata_collection_test.pf @@ -107,6 +107,7 @@ contains wind_mono_top_depth = 0, & adjust_theta = .false., & adjust_theta_above = 0.0_r_def, & + adjust_tracer_equation = .false., & adjust_vhv_wind=.false., & broken_w2_projection = .false., & consistent_metric = .false., & diff --git a/science/gungho/unit-test/kernel/transport/common/vorticity_advection_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/common/vorticity_advection_kernel_mod_test.pf index fd1051185..114c2b2b9 100644 --- a/science/gungho/unit-test/kernel/transport/common/vorticity_advection_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/common/vorticity_advection_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module vorticity_advection_kernel_mod_test - use constants_mod, only: i_def, r_def + use constants_mod, only: i_def, r_def, imdi use funit implicit none @@ -48,7 +48,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/common/w2_vorticity_advection_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/common/w2_vorticity_advection_kernel_mod_test.pf index 071d03792..744e562c5 100644 --- a/science/gungho/unit-test/kernel/transport/common/w2_vorticity_advection_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/common/w2_vorticity_advection_kernel_mod_test.pf @@ -8,7 +8,7 @@ !> module w2_vorticity_advection_kernel_mod_test - use constants_mod, only: i_def, r_def + use constants_mod, only: i_def, r_def, imdi use funit implicit none @@ -48,7 +48,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/mol/poly1d_advective_coeffs_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/mol/poly1d_advective_coeffs_kernel_mod_test.pf index d2e8ae4ee..e47ceb9f3 100644 --- a/science/gungho/unit-test/kernel/transport/mol/poly1d_advective_coeffs_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/mol/poly1d_advective_coeffs_kernel_mod_test.pf @@ -52,7 +52,7 @@ contains rehabilitate = .true., & vorticity_in_w1 = .true. ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/mol/poly1d_flux_coeffs_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/mol/poly1d_flux_coeffs_kernel_mod_test.pf index 26c6a3be1..e347ae2f2 100644 --- a/science/gungho/unit-test/kernel/transport/mol/poly1d_flux_coeffs_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/mol/poly1d_flux_coeffs_kernel_mod_test.pf @@ -52,7 +52,7 @@ contains rehabilitate = .true., & vorticity_in_w1 = .true. ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/mol/poly1d_vert_adv_coeffs_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/mol/poly1d_vert_adv_coeffs_kernel_mod_test.pf index 63a8e4996..dd681f833 100644 --- a/science/gungho/unit-test/kernel/transport/mol/poly1d_vert_adv_coeffs_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/mol/poly1d_vert_adv_coeffs_kernel_mod_test.pf @@ -80,6 +80,7 @@ contains wind_mono_top_depth = 0, & adjust_theta = .false., & adjust_theta_above = 0.0_r_def, & + adjust_tracer_equation = .false., & adjust_vhv_wind=.false., & dry_field_name='tracer', & profile_size = 1, & diff --git a/science/gungho/unit-test/kernel/transport/mol/poly2d_advective_coeffs_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/mol/poly2d_advective_coeffs_kernel_mod_test.pf index eec36089b..ee069f814 100644 --- a/science/gungho/unit-test/kernel/transport/mol/poly2d_advective_coeffs_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/mol/poly2d_advective_coeffs_kernel_mod_test.pf @@ -52,7 +52,7 @@ contains rehabilitate = .true., & vorticity_in_w1 = .true. ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/mol/poly2d_flux_coeffs_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/mol/poly2d_flux_coeffs_kernel_mod_test.pf index bc2105654..c693e1588 100644 --- a/science/gungho/unit-test/kernel/transport/mol/poly2d_flux_coeffs_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/mol/poly2d_flux_coeffs_kernel_mod_test.pf @@ -50,7 +50,8 @@ contains element_order_v = 0, & rehabilitate = .true., & vorticity_in_w1 = .true. ) - call init_chi_transforms() + + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/gungho/unit-test/kernel/transport/mol/polyv_wtheta_koren_kernel_mod_test.pf b/science/gungho/unit-test/kernel/transport/mol/polyv_wtheta_koren_kernel_mod_test.pf index f714c9b62..b9e58d149 100644 --- a/science/gungho/unit-test/kernel/transport/mol/polyv_wtheta_koren_kernel_mod_test.pf +++ b/science/gungho/unit-test/kernel/transport/mol/polyv_wtheta_koren_kernel_mod_test.pf @@ -72,6 +72,7 @@ contains cap_density_predictor = 0.001_r_def, & adjust_theta = .false., & adjust_theta_above = 0.0_r_def, & + adjust_tracer_equation = .false., & adjust_vhv_wind=.false., & min_val_abs_tol = -1.0e-12_r_def, & min_val_max_iterations = 100, & diff --git a/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf b/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf index e45d1fd81..c56647382 100644 --- a/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf +++ b/science/gungho/unit-test/orography/analytic_orography_field_spherical_mod_test.pf @@ -134,7 +134,7 @@ contains lambda_focus, & phi_focus ) ) - call init_chi_transforms() + call init_chi_transforms(geometry_spherical, topology_fully_periodic) end subroutine setUp diff --git a/science/linear/integration-test/nwp_gal9/ReadMe b/science/linear/integration-test/nwp_gal9/ReadMe new file mode 100644 index 000000000..911e9288f --- /dev/null +++ b/science/linear/integration-test/nwp_gal9/ReadMe @@ -0,0 +1 @@ +The nwp_gal9.nml matches the configuration from the default rose-app.conf, in linear_model. diff --git a/science/linear/integration-test/nwp_gal9/iodef.xml b/science/linear/integration-test/nwp_gal9/iodef.xml new file mode 100644 index 000000000..35ae0ee07 --- /dev/null +++ b/science/linear/integration-test/nwp_gal9/iodef.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + performance + 1.0 + + + + true + 50 + true + + + + + diff --git a/science/linear/integration-test/nwp_gal9/nwp_gal9.f90 b/science/linear/integration-test/nwp_gal9/nwp_gal9.f90 new file mode 100644 index 000000000..2280e549b --- /dev/null +++ b/science/linear/integration-test/nwp_gal9/nwp_gal9.f90 @@ -0,0 +1,144 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +!>@brief The top level program for the tangent linear tests. +!>@details The default is to run all available tests - which +!! test whether the linear code is tangent linear to the +!! corresponding nonlinear code. +program nwp_gal9 + + use driver_collections_mod, only: init_collections, final_collections + use driver_time_mod, only: init_time, final_time + use driver_comm_mod, only: init_comm, final_comm + use driver_log_mod, only: init_logger, final_logger + use driver_config_mod, only: init_config, final_config + use driver_modeldb_mod, only: modeldb_type + use lfric_mpi_mod, only: global_mpi + use gungho_mod, only: gungho_required_namelists + use log_mod, only: log_event, & + LOG_LEVEL_ERROR, & + LOG_LEVEL_INFO + use linear_driver_mod, only: initialise, finalise + use tl_test_driver_mod, only: run_timesteps, & + run_transport_control, & + run_semi_imp_alg, & + run_rhs_alg + + implicit none + + ! Model run working data set + type(modeldb_type) :: modeldb + character(*), parameter :: application_name = 'nwp_gal9' + character(:), allocatable :: filename + + ! Variables used for parsing command line arguments + integer :: length, status, nargs + character(len=0) :: dummy + character(len=:), allocatable :: program_name, test_flag + + ! Flags which determine the tests that will be carried out + logical :: do_test_timesteps = .false. + logical :: do_test_transport_control = .false. + logical :: do_test_semi_imp_alg = .false. + logical :: do_test_rhs_alg = .false. + + ! Usage message to print + character(len=256) :: usage_message + + modeldb%mpi => global_mpi + + call modeldb%configuration%initialise( application_name, table_len=10 ) + call modeldb%values%initialise('values', 5) + + call log_event( 'TL testing running ...', LOG_LEVEL_INFO ) + + ! Create the depository, prognostics and diagnostics field collections + call modeldb%fields%add_empty_field_collection("depository", table_len = 100) + call modeldb%fields%add_empty_field_collection("prognostic_fields", & + table_len = 100) + call modeldb%fields%add_empty_field_collection("diagnostic_fields", & + table_len = 100) + call modeldb%fields%add_empty_field_collection("lbc_fields", & + table_len = 100) + call modeldb%fields%add_empty_field_collection("radiation_fields", & + table_len = 100) + call modeldb%fields%add_empty_field_collection("fd_fields", & + table_len = 100) + + + call modeldb%io_contexts%initialise(application_name, 100) + + ! Parse command line parameters + call get_command_argument( 0, dummy, length, status ) + allocate(character(length)::program_name) + call get_command_argument( 0, program_name, length, status ) + nargs = command_argument_count() + + ! Print out usage message if wrong number of arguments is specified + if (nargs /= 2) then + write(usage_message,*) "Usage: ",trim(program_name), & + " " // & + " test_XXX with XXX in { " // & + " timesteps, " // & + " transport_control, " // & + " semi_imp_alg, " // & + " rhs_alg, " // & + " } " + call log_event( trim(usage_message), LOG_LEVEL_ERROR ) + end if + + call get_command_argument( 1, dummy, length, status ) + allocate( character(length) :: filename ) + call get_command_argument( 1, filename, length, status ) + + call get_command_argument( 2, dummy, length, status ) + allocate(character(length)::test_flag) + call get_command_argument( 2, test_flag, length, status ) + + ! Choose test case depending on flag provided in the first command + ! line argument + select case (trim(test_flag)) + case ("test_timesteps") + do_test_timesteps = .true. + case ("test_transport_control") + do_test_transport_control = .true. + case ("test_semi_imp_alg") + do_test_semi_imp_alg = .true. + case ("test_rhs_alg") + do_test_rhs_alg = .true. + case default + call log_event( "Unknown test", LOG_LEVEL_ERROR ) + end select + + call init_comm( application_name, modeldb ) + call init_config( filename, gungho_required_namelists, & + modeldb%configuration ) + call init_logger( modeldb%mpi%get_comm(), application_name ) + call init_collections() + call init_time( modeldb ) + call initialise( application_name, modeldb ) + + if (do_test_timesteps) then + call run_timesteps(modeldb) + endif + if (do_test_transport_control) then + call run_transport_control(modeldb) + endif + if (do_test_rhs_alg) then + call run_rhs_alg(modeldb) + endif + if (do_test_semi_imp_alg) then + call run_semi_imp_alg(modeldb) + endif + + call finalise( application_name, modeldb ) + call final_time( modeldb ) + call final_collections() + call final_logger( application_name ) + call final_config() + call final_comm( modeldb ) + +end program nwp_gal9 diff --git a/science/linear/integration-test/nwp_gal9/nwp_gal9.py b/science/linear/integration-test/nwp_gal9/nwp_gal9.py new file mode 100755 index 000000000..aa1414177 --- /dev/null +++ b/science/linear/integration-test/nwp_gal9/nwp_gal9.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +############################################################################## +# (c) Crown copyright 2026 Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## +''' +Run the linear model integration tests for the default (nwp_gal9) configuration + +''' +import os +import re +import sys + + +from testframework import LFRicLoggingTest, TestEngine, TestFailed + + +class TLTest(LFRicLoggingTest): + ''' + Run the linear model integration tests + ''' + + def __init__(self, flag): + self._flag = flag + if 'MPIEXEC_BROKEN' in os.environ: + TLTest.set_mpiexec_broken() + super(TLTest, self).__init__([sys.argv[1], + 'resources/nwp_gal9_configuration.nml', + 'test_' + self._flag], + processes=1, + name='tl_test.Log') + + def test(self, return_code, out, err): + ''' + Error messages if the test failed to run + ''' + if return_code != 0: + message = 'Test program failed with exit code: {code}' + raise TestFailed(message.format(code=return_code), + stdout=out, stderr=err, + log=self.getLFRicLoggingLog()) + + # "out" becomes self.getLFRicLoggingLog() when PE>1 + if not self.test_passed(out): + message = 'Test {} failed' + raise TestFailed(message.format(self._flag), + stdout=out, stderr=err, + log=self.getLFRicLoggingLog()) + + return 'TL test : '+self._flag + + def test_passed(self, out): + ''' + Examine the output to see if the validity test passed + ''' + success = False + pattern = re.compile(r'\s+test\s+.*?:\s*PASS\s*$') + for line in out.split("\n"): + match = pattern.search(line) + if match: + success = True + return success + +class tl_test_semi_imp_alg(TLTest): + ''' + Test the semi implicit timestep + ''' + def __init__(self): + flag = "semi_imp_alg" + super(tl_test_semi_imp_alg, self).__init__(flag) + + +class tl_test_rhs_alg(TLTest): + ''' + Test the right hand side forcing for the mixed solver + ''' + def __init__(self): + flag = "rhs_alg" + super(tl_test_rhs_alg, self).__init__(flag) + +class tl_test_transport_control(TLTest): + ''' + Test the transport + ''' + def __init__(self): + flag = "transport_control" + super(tl_test_transport_control, self).__init__(flag) + + +class tl_test_timesteps(TLTest): + ''' + Test running over multiple timesteps + ''' + def __init__(self): + flag = "timesteps" + super(tl_test_timesteps, self).__init__(flag) + +if __name__ == '__main__': + TestEngine.run(tl_test_rhs_alg()) + TestEngine.run(tl_test_transport_control()) + TestEngine.run(tl_test_semi_imp_alg()) + TestEngine.run(tl_test_timesteps()) + diff --git a/science/linear/integration-test/nwp_gal9/resources/mesh_C12_MG.nc b/science/linear/integration-test/nwp_gal9/resources/mesh_C12_MG.nc new file mode 100644 index 000000000..ebe518907 Binary files /dev/null and b/science/linear/integration-test/nwp_gal9/resources/mesh_C12_MG.nc differ diff --git a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml b/science/linear/integration-test/nwp_gal9/resources/nwp_gal9_configuration.nml similarity index 68% rename from applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml rename to science/linear/integration-test/nwp_gal9/resources/nwp_gal9_configuration.nml index 1296925a7..2277cacbc 100644 --- a/applications/jedi_lfric_tests/example_tlm_tests/configuration_dry_relaxed.nml +++ b/science/linear/integration-test/nwp_gal9/resources/nwp_gal9_configuration.nml @@ -1,53 +1,13 @@ -&jedi_lfric_tests -test_field='theta', -/ - -#### Configure JEDI-LFRIC - -&jedi_geometry -io_calender_start='2018-04-14T21:00:00', -io_path_inc_read='/data/users/lfric/data/jedi-lfric/Ticket354/pert_fields/lfric_diag', -io_path_state_read='/data/users/lfric/data/jedi-lfric/Ticket354/ls_fields/jedi_trajectory', -io_path_state_write='write_file', -io_setup_increment=.false., -io_time_step='P0DT1H0M0S', -/ -&jedi_state -state_time='2018-04-14 21:00:00', -use_pseudo_model=.true., -variables='theta','rho','u10m','exner','u_in_w3','v_in_w3','w_in_wth', -'m_v','m_cl','m_r','m_s', -/ -&jedi_increment -inc_time='2018-04-14 21:00:00', -initialise_via_read=.false., -variables='theta','rho','exner','u_in_w3','v_in_w3','w_in_wth','m_v', -'m_cl','m_r','m_s', -/ -&jedi_linear_model -nl_time_step='P0DT1H0M0S', -/ -&jedi_pseudo_model -initial_time='2018-04-14T21:00:00', -number_of_steps=9, -time_step='P0DT1H0M0S', -/ -&jedi_lfric_settings -forecast_length='P0DT6H0M0S', -/ - -#### Configure LFRic - &base_mesh -file_prefix='mesh_C12', +file_prefix='resources/mesh_C12_MG', geometry='spherical', prepartitioned=.false., -prime_mesh_name='C12', +prime_mesh_name='dynamics', topology='fully_periodic', / &boundaries limited_area=.false., -transport_overwrite_freq='final' +transport_overwrite_freq='final', / &checks limit_cfl=.false., @@ -60,6 +20,7 @@ cloud='none', dynamics='gungho', external_forcing=.false., iau=.false., +iau_sst=.false., iau_surf=.false., methane_oxidation=.false., orographic_drag='none', @@ -68,6 +29,15 @@ spectral_gwd='none', stochastic_physics='none', surface='none', / +&convection +dx_ref=50000.0, +l_cvdiag_ctop_qmax=.false., +qlmin=4.0e-4, +resdep_precipramp=.false., +/ +&cosp +l_cosp=.false., +/ &damping_layer dl_base=40000.0, dl_str=0.05, @@ -77,6 +47,7 @@ dl_type='standard', horizontal_limit='cap', horizontal_method='ffsl', n_dep_pt_iterations=1, +share_stencil_extent=.true., vertical_limit='exponential', vertical_method='timeaverage', vertical_sorting=.false., @@ -94,12 +65,14 @@ stretching_height=17507.0, stretching_method='smooth', / &files -ancil_directory='/data/users/lfric/data/ancils/basic-gal/yak/C12', +ancil_directory='/data/users/lfricadmin/data/ancils/basic-gal/yak/C12', checkpoint_stem_name='', -diag_stem_name='', +diag_stem_name='diagGungho', +ls_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +ls_filename='final_ls', orography_mean_ancil_path='orography/gmted_ramp2/qrparm.orog', -start_dump_directory='', -start_dump_filename='', +start_dump_directory='/data/users/lfricadmin/data/tangent-linear/Ticket354', +start_dump_filename='final_pert', / &finite_element cellshape='quadrilateral', @@ -111,41 +84,53 @@ rehabilitate=.true., vorticity_in_w1=.false., / &formulation -dlayer_on=.true., +dlayer_on=.false., dry_static_adjust=.true., eos_method='sampled', exner_from_eos=.false., +horizontal_physics_predictor=.false., +horizontal_transport_predictor=.false., init_exner_bt=.true., -l_multigrid=.false., +l_multigrid=.true., lagged_orog=.true., -moisture_formulation='dry', -moisture_in_solver=.false., +moisture_formulation='traditional', +moisture_in_solver=.true., p2theta_vert=.true., rotating=.true., shallow=.true., si_momentum_equation=.false., +theta_moist_source=.false., use_multires_coupling=.false., -use_physics=.false., +use_physics=.true., use_wavedynamics=.true., vector_invariant=.false., / &helmholtz_solver -fail_on_non_converged=.false., gcrk=8, -method='bicgstab', -monitor_convergence=.true., +method='prec_only', +monitor_convergence=.false., normalise=.true., -preconditioner='tridiagonal', +preconditioner='multigrid', si_pressure_a_tol=1.0e-8, si_pressure_maximum_iterations=400, si_pressure_tolerance=1.0e-4, / +&iau_addinf_io +/ +&iau_addinf_io +/ +&iau_ainc_io +/ +&iau_ainc_io +/ +&iau_bcorr_io +/ +&iau +/ &idealised f_lon_deg=0.0, -perturb_init=.false. -perturb_magnitude=0 -perturb_seed=0 -test='gravity_wave', +perturb_init=.false., +test='none', / &ideal_surface canopy_height=19.01,16.38,0.79,1.26,1.0, @@ -166,9 +151,9 @@ ancil_option='none', coarse_aerosol_ancil=.false., coarse_orography_ancil=.false., coarse_ozone_ancil=.false., -init_option='analytic', +init_option='fd_start_dump', lbc_option='none', -ls_option='analytic', +ls_option='file', model_eos_height=100, n_orog_smooth=0, read_w2h_wind=.true., @@ -180,10 +165,10 @@ zero_w2v_wind=.false., &initial_density density_background=0.1, density_max=2.0, -r1=0.0, -r2=0.0, -x1=0.0, -x2=0.0, +r1=0.4, +r2=0.4, +x1=0.4, +x2=-0.4, y1=0.0, y2=0.0, z1=0.0, @@ -195,7 +180,7 @@ surface_pressure=1000.0e2, / &initial_temperature bvf_square=0.0001, -pert_centre=120.0, +pert_centre=60.0, pert_width_scaling=1.0, perturb='none', theta_surf=300.0, @@ -204,11 +189,11 @@ theta_surf=300.0, / &initial_wind nl_constant=0.0, -profile='none', +profile='constant_uv', sbr_angle_lat=0.0, sbr_angle_lon=0.0, -smp_init_wind=.false., -u0=0.0, +smp_init_wind=.true., +u0=2.0, v0=0.0, wind_time_period=0.0, / @@ -220,37 +205,46 @@ diag_active_files='lfric_diag', diag_always_on_sampling=.false., diagnostic_frequency=8, file_convention='UGRID', +multifile_io=.false., nodal_output_on_w3=.false., subroutine_counters=.false., subroutine_timers=.true., timer_output_path='timer.txt', use_xios_io=.true., write_conservation_diag=.false., -write_diag=.true., +write_diag=.false., write_dump=.false., write_fluxes=.false., write_minmax_tseries=.false., / &linear +fixed_ls=.false., +l_stabilise_bl=.false., ls_read_w2h=.false., -pert_option='analytic', +max_bl_stabilisation=0.75, +n_bl_levels_to_stabilise=15, +pert_option='file', +/ +&linear_physics +l_boundary_layer=.false., / &logging -run_log_level='info', +log_to_rank_zero_only=.false., +run_log_level='debug', / &mixed_solver eliminate_variables='discrete', -fail_on_non_converged=.false., -gcrk=6, +fail_on_non_converged=.true., +gcrk=4, guess_np1=.false., -mixed_solver_a_tol=0.0, +mixed_solver_a_tol=1.0e-3, monitor_convergence=.true., normalise=.true., -reference_reset_time=3600.0, +reference_reset_time=1800.0, si_maximum_iterations=10, si_method='block_gcr', si_preconditioner='pressure', -si_tolerance=1.0e-5, +si_tolerance=1.0e-1, split_w=.true., / &mixing @@ -259,6 +253,14 @@ smagorinsky=.false., viscosity=.false., viscosity_mu=0.0, / +&multigrid +chain_mesh_tags='dynamics','multigrid_l1','multigrid_l2', +multigrid_chain_nitems=3, +n_coarsesmooth=4, +n_postsmooth=2, +n_presmooth=2, +smooth_relaxation=0.8, +/ &esm_couple l_esm_couple_test=.false., / @@ -266,15 +268,18 @@ l_esm_couple_test=.false., orog_init_option='ancil', / &partitioning +generate_inner_halos=.false., panel_decomposition='auto', -panel_xproc=1, +panel_xproc=6, panel_yproc=1, partitioner='cubedsphere', / &physics +configure_segments=.false., limit_drag_incs=.false., sample_physics_scalars=.true., sample_physics_winds=.true., +sample_physics_winds_correction=.false., / &planet cp=1005.0, @@ -286,10 +291,14 @@ scaling_factor=1.0, / &radiative_gases cfc113_rad_opt='off', -cfc11_rad_opt='off', -cfc12_rad_opt='off', -ch4_rad_opt='off', -co2_rad_opt='off', +cfc11_mix_ratio=1.110e-09, +cfc11_rad_opt='constant', +cfc12_mix_ratio=2.187e-09, +cfc12_rad_opt='constant', +ch4_mix_ratio=1.006e-06, +ch4_rad_opt='constant', +co2_mix_ratio=6.002e-04, +co2_rad_opt='constant', co_rad_opt='off', cs_rad_opt='off', h2_rad_opt='off', @@ -302,18 +311,19 @@ k_rad_opt='off', l_cts_fcg_rates=.false., li_rad_opt='off', n2_rad_opt='off', -n2o_rad_opt='off', +n2o_mix_ratio=4.945e-07, +n2o_rad_opt='constant', na_rad_opt='off', nh3_rad_opt='off', -o2_rad_opt='off', -o3_rad_opt='off', +o2_mix_ratio=0.2314, +o2_rad_opt='constant', +o3_rad_opt='ancil', rb_rad_opt='off', so2_rad_opt='off', tio_rad_opt='off', vo_rad_opt='off', / &solver -fail_on_non_converged=.false., gcrk=18, maximum_iterations=7, method='chebyshev', @@ -321,32 +331,35 @@ monitor_convergence=.false., preconditioner='diagonal', tolerance=1.0e-6, / +&specified_surface +/ &time calendar='timestep', -calendar_origin='2018-04-14 21:00:00', -calendar_start='2018-04-14 21:00:00', +calendar_origin='2016-01-01 15:00:00', +calendar_start='2016-01-01 15:00:00', calendar_type='gregorian', -timestep_end='13', +timestep_end='3', timestep_start='1', / ×tepping alpha=0.55, -dt=3600, +dt=1800, inner_iterations=2, method='semi_implicit', outer_iterations=2, runge_kutta_method='forward_euler', -spinup_alpha=.false., +spinup_alpha=.false.tau, tau_r=1.0, tau_t=1.0, tau_u=0.55, / &transport adjust_theta=.false., -adjust_vhv_wind=.false. +adjust_vhv_wind=.false., +ageofair_reset_level=10, broken_w2_projection=.false., calculate_detj='upwind', -cap_density_predictor=0.01, +cap_density_predictor=0.5, cfl_mol_1d_stab=1.0, cfl_mol_2d_stab=1.0, cfl_mol_3d_stab=1.0, @@ -356,40 +369,45 @@ dep_pt_stencil_extent=3, dry_field_name='density', enforce_min_value=5*.false., equation_form=1,2,2,2,2, -extended_mesh=.false., -ffsl_inner_order=2, -ffsl_outer_order=2, +ffsl_inner_order=0, +ffsl_outer_order=1, ffsl_splitting=5*1, -ffsl_unity_3d=.false. -ffsl_vertical_order=5*2 -field_names='density','potential_temperature','wind','moisture','cloud', +ffsl_unity_3d=.false., +ffsl_vertical_order=2,2,1,2,2, +field_names='density','potential_temperature','wind','moisture', +'con_tracer', fv_horizontal_order=2, fv_vertical_order=2, horizontal_method=5*1, horizontal_monotone=5*1, log_space=5*.false., -max_vert_cfl_calc='uniform', +max_vert_cfl_calc='dep_point', min_val_abs_tol=-1.0e-12, min_val_max_iterations=10, min_val_method='iterative', min_value=0.0,0.0,-99999999.0,0.0,0.0, oned_reconstruction=.false., operators='fv', +panel_edge_high_order=.true., +panel_edge_treatment='none', profile_size=5, reversible=5*.false., runge_kutta_method='ssp3', scheme=5*1, si_outer_transport='none', slice_order='parabola', +special_edges_monotone=5*1, splitting=5*1, substep_transport='off', theta_dispersion_correction=.false., theta_variable='dry', +transport_ageofair=.false., use_density_predictor=.false., vertical_method=5*1, vertical_monotone=5*1, -vertical_monotone_order=5*1, +vertical_monotone_order=5*3, vertical_sl_order='cubic', +wind_mono_top=.false., / &validity_test number_gamma_values=2, diff --git a/science/linear/integration-test/runge_kutta/iodef.xml b/science/linear/integration-test/runge_kutta/iodef.xml index 21fe7a0b0..1c4e6d3c3 100644 --- a/science/linear/integration-test/runge_kutta/iodef.xml +++ b/science/linear/integration-test/runge_kutta/iodef.xml @@ -262,7 +262,7 @@ performance - 1.0 + 1.0 diff --git a/science/linear/integration-test/runge_kutta/resources/runge_kutta_configuration.nml b/science/linear/integration-test/runge_kutta/resources/runge_kutta_configuration.nml index 9298f96f7..a1361ed46 100644 --- a/science/linear/integration-test/runge_kutta/resources/runge_kutta_configuration.nml +++ b/science/linear/integration-test/runge_kutta/resources/runge_kutta_configuration.nml @@ -131,7 +131,7 @@ subroutine_counters=.false., subroutine_timers=.true., use_xios_io=.false., write_conservation_diag=.false., -write_diag=.true., +write_diag=.false., write_dump=.false., write_fluxes=.false., write_minmax_tseries=.false., @@ -139,6 +139,10 @@ write_minmax_tseries=.false., &linear fixed_ls=.false. pert_option='random', +transport_efficiency=.false. +/ +&linear_physics +l_boundary_layer=.false., / &logging run_log_level='info', @@ -194,7 +198,7 @@ tolerance=1.0e-6, / &time calendar='timestep', -timestep_end='1', +timestep_end='6', timestep_start='1', calendar_type='gregorian', calendar_start='2016-01-01 15:00:00', diff --git a/science/linear/integration-test/runge_kutta/runge_kutta.f90 b/science/linear/integration-test/runge_kutta/runge_kutta.f90 index f460201ac..301f0b7fa 100644 --- a/science/linear/integration-test/runge_kutta/runge_kutta.f90 +++ b/science/linear/integration-test/runge_kutta/runge_kutta.f90 @@ -10,21 +10,19 @@ !! corresponding nonlinear code. program runge_kutta - use configuration_mod, only: read_configuration, final_configuration use driver_collections_mod, only: init_collections, final_collections use driver_time_mod, only: init_time, final_time + use driver_comm_mod, only: init_comm, final_comm + use driver_log_mod, only: init_logger, final_logger + use driver_config_mod, only: init_config, final_config use driver_modeldb_mod, only: modeldb_type - use halo_comms_mod, only: initialise_halo_comms, & - finalise_halo_comms - use lfric_mpi_mod, only: create_comm, destroy_comm, global_mpi, & - lfric_comm_type - use log_mod, only: initialise_logging, finalise_logging, & - log_event, & + use lfric_mpi_mod, only: global_mpi + use gungho_mod, only: gungho_required_namelists + use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO - use tl_test_driver_mod, only: initialise, & - finalise, & - run_timesteps, & + use linear_driver_mod, only: initialise, finalise + use tl_test_driver_mod, only: run_timesteps_random, & run_kinetic_energy_gradient, & run_advect_density_field, & run_advect_theta_field, & @@ -39,7 +37,6 @@ program runge_kutta ! Model run working data set type(modeldb_type) :: modeldb character(*), parameter :: application_name = "runge_kutta" - character(:), allocatable :: filename ! Variables used for parsing command line arguments @@ -47,8 +44,6 @@ program runge_kutta character(len=0) :: dummy character(len=:), allocatable :: program_name, test_flag - type(lfric_comm_type) :: communicator - ! Flags which determine the tests that will be carried out logical :: do_test_timesteps = .false. logical :: do_test_kinetic_energy_gradient = .false. @@ -65,11 +60,8 @@ program runge_kutta modeldb%mpi => global_mpi - call create_comm( communicator ) - call modeldb%mpi%initialise( communicator ) - call initialise_logging( communicator%get_comm_mpi_val(), & - "linear_integration-runge_kutta-test" ) - call initialise_halo_comms( communicator ) + call modeldb%configuration%initialise( application_name, table_len=10 ) + call modeldb%values%initialise('values', 5) call log_event( 'TL testing running ...', LOG_LEVEL_INFO ) @@ -86,7 +78,7 @@ program runge_kutta call modeldb%fields%add_empty_field_collection("fd_fields", & table_len = 100) - call modeldb%io_contexts%initialise(program_name, 100) + call modeldb%io_contexts%initialise(application_name, 100) ! Parse command line parameters call get_command_argument( 0, dummy, length, status ) @@ -145,16 +137,16 @@ program runge_kutta call log_event( "Unknown test", LOG_LEVEL_ERROR ) end select - call modeldb%configuration%initialise( program_name, table_len=10 ) - call read_configuration( filename, modeldb%configuration ) - deallocate( filename ) - + call init_comm( application_name, modeldb ) + call init_config( filename, gungho_required_namelists, & + modeldb%configuration ) + call init_logger( modeldb%mpi%get_comm(), application_name ) call init_collections() call init_time( modeldb ) - call initialise( application_name, modeldb, modeldb%calendar ) + call initialise( application_name, modeldb ) if (do_test_timesteps) then - call run_timesteps(modeldb) + call run_timesteps_random(modeldb) endif if (do_test_kinetic_energy_gradient) then call run_kinetic_energy_gradient(modeldb) @@ -184,9 +176,8 @@ program runge_kutta call finalise( application_name, modeldb ) call final_time( modeldb ) call final_collections() - call final_configuration() - call finalise_halo_comms() - call finalise_logging() - call destroy_comm() + call final_logger( application_name ) + call final_config() + call final_comm( modeldb ) end program runge_kutta diff --git a/science/linear/integration-test/semi_implicit/iodef.xml b/science/linear/integration-test/semi_implicit/iodef.xml index 48b58e609..341d11896 100644 --- a/science/linear/integration-test/semi_implicit/iodef.xml +++ b/science/linear/integration-test/semi_implicit/iodef.xml @@ -261,7 +261,7 @@ performance - 1.0 + 1.0 diff --git a/science/linear/integration-test/semi_implicit/resources/semi_implicit_configuration.nml b/science/linear/integration-test/semi_implicit/resources/semi_implicit_configuration.nml index 2b208a451..ae4d3bf12 100644 --- a/science/linear/integration-test/semi_implicit/resources/semi_implicit_configuration.nml +++ b/science/linear/integration-test/semi_implicit/resources/semi_implicit_configuration.nml @@ -132,7 +132,7 @@ subroutine_counters=.false., subroutine_timers=.true., use_xios_io=.false., write_conservation_diag=.false., -write_diag=.true., +write_diag=.false., write_dump=.false., write_fluxes=.false., write_minmax_tseries=.false., @@ -140,6 +140,10 @@ write_minmax_tseries=.false., &linear fixed_ls=.false. pert_option='random', +transport_efficiency=.false. +/ +&linear_physics +l_boundary_layer=.false., / &logging run_log_level='info', diff --git a/science/linear/integration-test/semi_implicit/semi_implicit.f90 b/science/linear/integration-test/semi_implicit/semi_implicit.f90 index af625729c..57ac5a80d 100644 --- a/science/linear/integration-test/semi_implicit/semi_implicit.f90 +++ b/science/linear/integration-test/semi_implicit/semi_implicit.f90 @@ -10,35 +10,25 @@ !! corresponding nonlinear code. program semi_implicit - use configuration_mod, only: read_configuration, final_configuration use driver_collections_mod, only: init_collections, final_collections use driver_time_mod, only: init_time, final_time + use driver_comm_mod, only: init_comm, final_comm + use driver_log_mod, only: init_logger, final_logger + use driver_config_mod, only: init_config, final_config use driver_modeldb_mod, only: modeldb_type - use halo_comms_mod, only: initialise_halo_comms, finalise_halo_comms - use lfric_mpi_mod, only: global_mpi, & - create_comm, destroy_comm, & - lfric_comm_type - use log_mod, only: initialise_logging, finalise_logging, & - log_event, & + use lfric_mpi_mod, only: global_mpi + use gungho_mod, only: gungho_required_namelists + use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO - use namelist_collection_mod, only: namelist_collection_type - use tl_test_driver_mod, only: initialise, & - finalise, & - run_timesteps, & - run_transport_control, & - run_semi_imp_alg, & - run_rhs_sample_eos, & - run_rhs_project_eos, & - run_rhs_alg + use linear_driver_mod, only: initialise, finalise + use tl_test_driver_mod, only: run_timesteps_random implicit none ! Model run working data set type(modeldb_type) :: modeldb - character(*), parameter :: application_name = 'semi_implicit' - character(:), allocatable :: filename ! Variables used for parsing command line arguments @@ -46,26 +36,16 @@ program semi_implicit character(len=0) :: dummy character(len=:), allocatable :: program_name, test_flag - type(lfric_comm_type) :: communicator - ! Flags which determine the tests that will be carried out logical :: do_test_timesteps = .false. - logical :: do_test_transport_control = .false. - logical :: do_test_semi_imp_alg = .false. - logical :: do_test_rhs_alg = .false. - logical :: do_test_rhs_project_eos = .false. - logical :: do_test_rhs_sample_eos = .false. ! Usage message to print character(len=256) :: usage_message modeldb%mpi => global_mpi - call create_comm( communicator ) - call modeldb%mpi%initialise( communicator ) - call initialise_logging( communicator%get_comm_mpi_val(), & - "linear_interface-semi_implicit-test" ) - call initialise_halo_comms( communicator ) + call modeldb%configuration%initialise( application_name, table_len=10 ) + call modeldb%values%initialise('values', 5) call log_event( 'TL testing running ...', LOG_LEVEL_INFO ) @@ -82,7 +62,8 @@ program semi_implicit call modeldb%fields%add_empty_field_collection("fd_fields", & table_len = 100) - call modeldb%io_contexts%initialise(program_name, 100) + + call modeldb%io_contexts%initialise(application_name, 100) ! Parse command line parameters call get_command_argument( 0, dummy, length, status ) @@ -99,8 +80,6 @@ program semi_implicit " transport_control, " // & " semi_imp_alg, " // & " rhs_alg, " // & - " rhs_project_eos, " // & - " rhs_sample_eos, " // & " } " call log_event( trim(usage_message), LOG_LEVEL_ERROR ) end if @@ -118,53 +97,27 @@ program semi_implicit select case (trim(test_flag)) case ("test_timesteps") do_test_timesteps = .true. - case ("test_transport_control") - do_test_transport_control = .true. - case ("test_semi_imp_alg") - do_test_semi_imp_alg = .true. - case ("test_rhs_alg") - do_test_rhs_alg = .true. - case ("test_rhs_project_eos") - do_test_rhs_project_eos = .true. - case ("test_rhs_sample_eos") - do_test_rhs_sample_eos = .true. case default call log_event( "Unknown test", LOG_LEVEL_ERROR ) end select - call modeldb%configuration%initialise( program_name, table_len=10 ) - call read_configuration( filename, modeldb%configuration ) - deallocate( filename ) - + call init_comm( application_name, modeldb ) + call init_config( filename, gungho_required_namelists, & + modeldb%configuration ) + call init_logger( modeldb%mpi%get_comm(), application_name ) call init_collections() call init_time( modeldb ) - call initialise( application_name, modeldb, modeldb%calendar ) + call initialise( application_name, modeldb ) if (do_test_timesteps) then - call run_timesteps(modeldb) - endif - if (do_test_transport_control) then - call run_transport_control(modeldb) - endif - if (do_test_rhs_alg) then - call run_rhs_alg(modeldb) - endif - if (do_test_rhs_project_eos) then - call run_rhs_project_eos(modeldb) - endif - if (do_test_rhs_sample_eos) then - call run_rhs_sample_eos(modeldb) - endif - if (do_test_semi_imp_alg) then - call run_semi_imp_alg(modeldb) + call run_timesteps_random(modeldb) endif call finalise( application_name, modeldb ) call final_time( modeldb ) call final_collections() - call final_configuration() - call finalise_halo_comms() - call finalise_logging() - call destroy_comm() + call final_logger( application_name ) + call final_config() + call final_comm( modeldb ) end program semi_implicit diff --git a/science/linear/integration-test/semi_implicit/semi_implicit.py b/science/linear/integration-test/semi_implicit/semi_implicit.py index af210aff1..534eb9897 100755 --- a/science/linear/integration-test/semi_implicit/semi_implicit.py +++ b/science/linear/integration-test/semi_implicit/semi_implicit.py @@ -63,43 +63,6 @@ def test_passed(self, out): success = True return success - -class tl_test_semi_imp_alg(TLTest): - ''' - Test the semi implicit timestep - ''' - def __init__(self): - flag = "semi_imp_alg" - super(tl_test_semi_imp_alg, self).__init__(flag) - - -class tl_test_rhs_alg(TLTest): - ''' - Test the right hand side forcing for the mixed solver - ''' - def __init__(self): - flag = "rhs_alg" - super(tl_test_rhs_alg, self).__init__(flag) - -class tl_test_rhs_sample_eos(TLTest): - def __init__(self): - flag = "rhs_sample_eos" - super(tl_test_rhs_sample_eos, self).__init__(flag) - -class tl_test_rhs_project_eos(TLTest): - def __init__(self): - flag = "rhs_project_eos" - super(tl_test_rhs_project_eos, self).__init__(flag) - -class tl_test_transport_control(TLTest): - ''' - Test the transport - ''' - def __init__(self): - flag = "transport_control" - super(tl_test_transport_control, self).__init__(flag) - - class tl_test_timesteps(TLTest): ''' Test running over multiple timesteps @@ -109,9 +72,4 @@ def __init__(self): super(tl_test_timesteps, self).__init__(flag) if __name__ == '__main__': - TestEngine.run( tl_test_rhs_sample_eos() ) - TestEngine.run( tl_test_rhs_project_eos() ) - TestEngine.run(tl_test_transport_control()) - TestEngine.run( tl_test_semi_imp_alg() ) - TestEngine.run( tl_test_rhs_alg() ) - TestEngine.run(tl_test_timesteps()) + TestEngine.run( tl_test_timesteps() ) diff --git a/science/linear/integration-test/tl_test/tl_test_advect_density_field_mod.x90 b/science/linear/integration-test/tl_test/tl_test_advect_density_field_mod.x90 index c7ee7136f..b704f3475 100644 --- a/science/linear/integration-test/tl_test/tl_test_advect_density_field_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_advect_density_field_mod.x90 @@ -185,7 +185,6 @@ module tl_test_advect_density_field_mod call invoke( X_minus_Y( diff, n2_advection_inc, n1_advection_inc ), & inc_X_minus_Y( diff, p_advection_inc ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ', gamma_u, ' norm = ', norm_diff diff --git a/science/linear/integration-test/tl_test/tl_test_advect_theta_field_mod.x90 b/science/linear/integration-test/tl_test/tl_test_advect_theta_field_mod.x90 index f712ba304..4630bdf10 100644 --- a/science/linear/integration-test/tl_test/tl_test_advect_theta_field_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_advect_theta_field_mod.x90 @@ -188,8 +188,6 @@ module tl_test_advect_theta_field_mod inc_X_minus_Y( diff, p_advection_inc ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) - write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ' , gamma_u , ' norm = ' , norm_diff diff --git a/science/linear/integration-test/tl_test/tl_test_convergence_rate_check.f90 b/science/linear/integration-test/tl_test/tl_test_convergence_rate_check.f90 index a13655df9..b090ba7fc 100644 --- a/science/linear/integration-test/tl_test/tl_test_convergence_rate_check.f90 +++ b/science/linear/integration-test/tl_test/tl_test_convergence_rate_check.f90 @@ -6,7 +6,7 @@ !>@brief Test the convergence rate (Taylor remainder convergence). module tl_test_convergence_rate_check - use constants_mod, only: r_def, str_def + use constants_mod, only: r_def, str_def, i_def use log_mod, only: log_event, & log_scratch_space, & LOG_LEVEL_INFO @@ -14,17 +14,129 @@ module tl_test_convergence_rate_check implicit none private - public convergence_rate_check + public convergence_pass_string, & + array_convergence_rate_check, & + convergence_rate_check + +contains + + !> @brief Test the convergence rate, with application of square root. + !> @details If the convergence rate is not close to 4, within the + !! specified tolerance, set the pass string to FAIL. + !> @param[in] name Variable or test name + !> @param[in] norm Current norm + !> @param[in] norm_prev Previous norm + !> @param[in,out] pass_str Pass string (either PASS or FAIL) + !> @param[in] tol Tolerance + subroutine convergence_pass_string( name, norm, norm_prev, pass_str, tol ) + implicit none + + real(r_def), intent(in) :: norm, norm_prev + character(len=4), intent(inout) :: pass_str + real(r_def), intent(in) :: tol + character(str_def), intent(in) :: name + + real(r_def) :: conv_rate + + ! Let the error between the nonlinear (N) difference and the linear (L) be + ! E(g) = || N(x + g dx) - N(x) - g Ldx || = O(g^2) + ! where g is a scalar, x and dx are vectors, O is the order + ! and || . || = (x^T x)^1/2 is the L2 norm. + ! + ! Then the ratio + ! E(2g) / E(g) = O(4 g^2) / O(g^2) = 4 + ! i.e. we need to check whether the convergence rate is close to 4. + + ! The norms have not had a square root applied yet. + conv_rate = sqrt(norm_prev / norm) + + if ( abs( conv_rate - 4.0_r_def ) >= tol ) then + pass_str = "FAIL" + else + pass_str = "PASS" + end if + + write( log_scratch_space, '(A, A, A, E16.8, A, E16.8)') & + name, pass_str, " Convergence rate: ", conv_rate, " Tolerance: ", tol + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + end subroutine convergence_pass_string + + !> @brief Test the convergence rate for individual variables and the sum. + !> @details Calculate the convergence rate based on the norms + !> at two different iterations, and compare with the + !> expected value. Print out either PASS or FAIL, which + !> will then be used by the top level integration test. + !> @param[in] array_norm Norm at second iteration + !> @param[in] array_norm_prev Norm at first iteration + !> @param[in] array_names Name of the variable being tested + !> @param[in] n_variables Array lengths (number of variables) + !> @param[in] label Test name + !> @param[in] tol Tolerance value + subroutine array_convergence_rate_check( array_norm, array_norm_prev, array_names, n_variables, label, tol, indiv_tol) + integer(i_def), intent(in) :: n_variables + real(r_def), intent(in) :: array_norm(n_variables) + real(r_def), intent(in) :: array_norm_prev(n_variables) + character(str_def), intent(in) :: array_names(n_variables) + character(str_def), intent(in) :: label + real(r_def), optional, intent(in) :: tol + real(r_def), optional, intent(in) :: indiv_tol + real(r_def) :: tolerance, individual_tolerance + character(len=4) :: pass_str_arr(n_variables) + character(len=4) :: sum_pass_str, pass_str + character(str_def), parameter :: sum_name = "sum" + integer(i_def) :: i + real(r_def) :: sum, sum_prev - contains + call log_event( "Checking convergence rate", LOG_LEVEL_INFO ) + + if ( present(tol) ) then + tolerance = tol + else + tolerance = 1.0E-8_r_def + end if + + if ( present(indiv_tol) ) then + individual_tolerance = indiv_tol + else + individual_tolerance = 1.0E-8_r_def + end if + + sum = 0.0_r_def + sum_prev = 0.0_r_def + do i= 1, n_variables + ! Check individual convergence rates + call convergence_pass_string( & + array_names(i), array_norm(i), & + array_norm_prev(i), pass_str_arr(i), & + individual_tolerance ) + + ! Weighted sum + sum = sum + array_norm(i) / array_norm_prev(i) + sum_prev = sum_prev + array_norm_prev(i) / array_norm_prev(i) + end do + + call convergence_pass_string( & + sum_name, sum, sum_prev, sum_pass_str, tolerance) + + pass_str = "PASS" + do i= 1, n_variables + if ( pass_str_arr(i) == "FAIL" ) pass_str = "FAIL" + end do + if ( sum_pass_str == "FAIL" ) pass_str = "FAIL" + + write(log_scratch_space,'(" test",A32," : ",A4)') trim(label), pass_str + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + end subroutine array_convergence_rate_check !> @brief Calculate and test the convergence rate. !> @details Calculate the convergence rate based on the norms !> at two different iterations, and compare with the !> expected value. Print out either PASS or FAIL, which !> will then be used by the top level integration test. - !> @param[in] norm_diff Norm at first iteration - !> @param[in] norm_diff_prev Norm at second iteration + !> @param[in] norm_diff Norm at second iteration + !> @param[in] norm_diff_prev Norm at first iteration !> @param[in] label Name of the code being tested !> @param[in] tol Tolerance value subroutine convergence_rate_check( norm_diff, norm_diff_prev, label, tol ) @@ -35,7 +147,6 @@ subroutine convergence_rate_check( norm_diff, norm_diff_prev, label, tol ) character(str_def), intent(in) :: label real(r_def), optional, intent(in) :: tol real(r_def) :: tolerance - real(r_def) :: conv_rate character(len=4) :: pass_str if ( present(tol) ) then @@ -44,23 +155,8 @@ subroutine convergence_rate_check( norm_diff, norm_diff_prev, label, tol ) tolerance = 1.0E-8_r_def end if - conv_rate = norm_diff_prev/ norm_diff - - - - write( log_scratch_space, '(A)' ) & - "TL Test: " // trim(label) - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - write( log_scratch_space, '(A, E16.8)') & - "Convergence rate: ", conv_rate - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - - if ( abs(conv_rate - 4.0_r_def ) < tolerance ) then - pass_str = "PASS" - else - pass_str = "FAIL" - end if + call convergence_pass_string( & + label, norm_diff, norm_diff_prev, pass_str, tolerance) write(log_scratch_space,'(" test",A32," : ",A4)') trim(label), pass_str call log_event( log_scratch_space, LOG_LEVEL_INFO ) diff --git a/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 b/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 index b93d850df..0d1c7e5ed 100644 --- a/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 +++ b/science/linear/integration-test/tl_test/tl_test_driver_mod.f90 @@ -48,13 +48,13 @@ module tl_test_driver_mod use tl_test_rhs_alg_mod, only : test_rhs_alg use tl_test_semi_imp_alg_mod, only : test_semi_imp_alg use tl_test_timesteps_alg_mod, only : test_timesteps + use tl_test_timesteps_random_alg_mod, only : test_timesteps_random implicit none private - public initialise, & - finalise, & - run_timesteps, & + public run_timesteps, & + run_timesteps_random, & run_kinetic_energy_gradient, & run_advect_density_field, & run_advect_theta_field, & @@ -72,109 +72,47 @@ module tl_test_driver_mod type(mesh_type), pointer :: mesh => null() type(mesh_type), pointer :: twod_mesh => null() - type(mesh_type), pointer :: aerosol_mesh => null() - type(mesh_type), pointer :: aerosol_twod_mesh => null() contains !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !>@brief Sets up the required state in preparation for run. - !>@param [in] program_name An identifier given to the model being run - !>@param [in,out] modeldb The structure that holds model state - !> - subroutine initialise( program_name, modeldb, calendar ) + !>@brief Tests the tangent linear model for multiple timesteps + !>@param [in,out] modeldb The structure that holds model state + subroutine run_timesteps(modeldb) implicit none - character(*), intent(in) :: program_name - type(modeldb_type), intent(inout) :: modeldb - class(calendar_type), intent(in) :: calendar - - type(gungho_time_axes_type) :: model_axes - type(io_value_type) :: temp_corr_io_value - type(io_value_type) :: random_seed_io_value - integer(i_def) :: random_seed_size - real(r_def), allocatable :: real_array(:) - - call modeldb%values%initialise( 'values', 5 ) - - ! Initialise infrastructure and setup constants - ! - call initialise_infrastructure( program_name, modeldb ) - - ! Add a place to store time axes in modeldb - call modeldb%values%add_key_value('model_axes', model_axes) + type(modeldb_type), intent(inout) :: modeldb - ! Get primary and 2D meshes for initialising model data mesh => mesh_collection%get_mesh(prime_mesh_name) twod_mesh => mesh_collection%get_mesh(mesh, TWOD) - ! Assume aerosol mesh is the same as dynamics mesh - aerosol_mesh => mesh - aerosol_twod_mesh => twod_mesh - - ! gungho_init_field() expects these values to exist. The dependency of - ! the linear application tests on this procedure will hopefully be resolved - ! in the future, at which point this initialisation may be removed. - ! - call temp_corr_io_value%init('temperature_correction_rate', [0.0_r_def]) - call modeldb%values%add_key_value( 'temperature_correction_io_value', & - temp_corr_io_value ) - call modeldb%values%add_key_value( 'total_dry_mass', 0.0_r_def ) - call modeldb%values%add_key_value( 'total_energy', 0.0_r_def ) - call modeldb%values%add_key_value( 'total_energy_previous', 0.0_r_def ) - if ( stochastic_physics == stochastic_physics_um ) then - ! Random seed for stochastic physics - call random_seed(size = random_seed_size) - allocate(real_array(random_seed_size)) - real_array(1:random_seed_size) = 0.0_r_def - call random_seed_io_value%init("random_seed", real_array) - call modeldb%values%add_key_value( 'random_seed_io_value', & - random_seed_io_value ) - deallocate(real_array) - end if - - ! Instantiate the fields stored in model_data - call create_model_data( modeldb, & - mesh, & - twod_mesh, & - aerosol_mesh, & - aerosol_twod_mesh ) - - ! Instantiate the linearisation state - call linear_create_ls( modeldb, mesh ) - - ! Initialise the fields stored in the model_data prognostics. This needs - ! to be done before initialise_model. - call initialise_model_data( modeldb, mesh, twod_mesh ) - - ! Model configuration initialisation - call initialise_model( mesh, & - modeldb ) - - ! Initialise the linearisation state - call linear_init_ls( mesh, twod_mesh, modeldb ) - - ! Finalise model - call finalise_model(modeldb) - - end subroutine initialise + call test_timesteps( modeldb, & + mesh, & + twod_mesh, & + modeldb%clock ) + + end subroutine run_timesteps !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !>@brief Tests the tangent linear model for multiple timesteps + !! using prescribed random data for the initial conditions !>@param [in,out] modeldb The structure that holds model state - subroutine run_timesteps(modeldb) + subroutine run_timesteps_random(modeldb) implicit none type(modeldb_type), intent(inout) :: modeldb - call test_timesteps( modeldb, & - mesh, & - twod_mesh, & - modeldb%clock ) + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) - end subroutine run_timesteps + call test_timesteps_random( modeldb, & + mesh, & + twod_mesh, & + modeldb%clock ) + + end subroutine run_timesteps_random !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !>@brief Tests the tangent linear model kinetic energy gradient kernel @@ -185,6 +123,9 @@ subroutine run_kinetic_energy_gradient(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_kinetic_energy_gradient( modeldb, & mesh, & twod_mesh ) @@ -200,6 +141,9 @@ subroutine run_advect_density_field(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_advect_density_field( modeldb, & mesh, & twod_mesh ) @@ -215,6 +159,9 @@ subroutine run_advect_theta_field(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_advect_theta_field( modeldb, & mesh, & twod_mesh ) @@ -230,6 +177,9 @@ subroutine run_vorticity_advection(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_vorticity_advection( modeldb, & mesh, & twod_mesh ) @@ -245,6 +195,9 @@ subroutine run_project_eos_pressure(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_project_eos_pressure( modeldb, & mesh, & twod_mesh ) @@ -260,6 +213,9 @@ subroutine run_sample_eos_pressure(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_sample_eos_pressure( modeldb, & mesh, & twod_mesh ) @@ -275,6 +231,9 @@ subroutine run_hydrostatic(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_hydrostatic( modeldb, & mesh, & twod_mesh ) @@ -290,6 +249,9 @@ subroutine run_pressure_gradient_bd(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_pressure_gradient_bd( modeldb, & mesh, & twod_mesh ) @@ -305,6 +267,8 @@ subroutine run_rk_alg(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + call test_rk_alg( modeldb, & mesh) @@ -319,6 +283,9 @@ subroutine run_transport_control(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_transport_control( modeldb, & mesh, & twod_mesh ) @@ -334,6 +301,9 @@ subroutine run_semi_imp_alg(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_semi_imp_alg( modeldb, & mesh, & twod_mesh ) @@ -349,6 +319,9 @@ subroutine run_rhs_alg(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_rhs_alg( modeldb, & mesh, & twod_mesh ) @@ -364,6 +337,9 @@ subroutine run_rhs_project_eos(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_rhs_project_eos( modeldb, & mesh, & twod_mesh ) @@ -379,31 +355,13 @@ subroutine run_rhs_sample_eos(modeldb) type(modeldb_type), intent(inout) :: modeldb + mesh => mesh_collection%get_mesh(prime_mesh_name) + twod_mesh => mesh_collection%get_mesh(mesh, TWOD) + call test_rhs_sample_eos( modeldb, & mesh, & twod_mesh ) end subroutine run_rhs_sample_eos - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !>@brief Tidies up after a run. - !>@param [in] program_name An identifier given to the model being run - !>@param [in,out] modeldb The structure that holds model state - subroutine finalise( program_name, modeldb ) - - implicit none - - character(*), intent(in) :: program_name - type(modeldb_type), intent(inout) :: modeldb - - call log_event( 'Finalising '//program_name//' ...', LOG_LEVEL_ALWAYS ) - - ! Destroy the fields stored in model_data - call finalise_model_data( modeldb ) - - ! Finalise infrastructure and constants - call finalise_infrastructure(modeldb) - - end subroutine finalise - end module tl_test_driver_mod diff --git a/science/linear/integration-test/tl_test/tl_test_hydrostatic_mod.x90 b/science/linear/integration-test/tl_test/tl_test_hydrostatic_mod.x90 index fbcb7baad..5aa4f198b 100644 --- a/science/linear/integration-test/tl_test/tl_test_hydrostatic_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_hydrostatic_mod.x90 @@ -189,8 +189,6 @@ module tl_test_hydrostatic_mod inc_X_minus_Y( diff, p_rhs_u ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) - write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ', gamma, ' norm = ', norm_diff diff --git a/science/linear/integration-test/tl_test/tl_test_kinetic_energy_gradient_mod.x90 b/science/linear/integration-test/tl_test/tl_test_kinetic_energy_gradient_mod.x90 index 2138662af..f2910b1b3 100644 --- a/science/linear/integration-test/tl_test/tl_test_kinetic_energy_gradient_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_kinetic_energy_gradient_mod.x90 @@ -135,7 +135,6 @@ module tl_test_kinetic_energy_gradient_mod call invoke( X_minus_Y( diff, n2_rhs_u, n1_rhs_u ), & inc_X_minus_Y( diff, p_rhs_u ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ', gamma, ' norm = ', norm_diff diff --git a/science/linear/integration-test/tl_test/tl_test_pressure_grad_bd_mod.x90 b/science/linear/integration-test/tl_test/tl_test_pressure_grad_bd_mod.x90 index 8bb6117a3..5a9f0210e 100644 --- a/science/linear/integration-test/tl_test/tl_test_pressure_grad_bd_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_pressure_grad_bd_mod.x90 @@ -213,8 +213,6 @@ module tl_test_pressure_grad_bd_mod inc_X_minus_Y( diff, p_rhs_u ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) - write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ', gamma, ' norm = ', norm_diff diff --git a/science/linear/integration-test/tl_test/tl_test_project_eos_pressure_mod.x90 b/science/linear/integration-test/tl_test/tl_test_project_eos_pressure_mod.x90 index 01ef9b694..9fc26e063 100644 --- a/science/linear/integration-test/tl_test/tl_test_project_eos_pressure_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_project_eos_pressure_mod.x90 @@ -195,7 +195,6 @@ module tl_test_project_eos_pressure_mod call invoke( X_minus_Y( diff, n2_exner, n1_exner ), & inc_X_minus_Y( diff, p_exner ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ', gamma , ' norm = ', norm_diff diff --git a/science/linear/integration-test/tl_test/tl_test_rhs_alg_mod.x90 b/science/linear/integration-test/tl_test/tl_test_rhs_alg_mod.x90 index 1c483372f..6207afcd8 100644 --- a/science/linear/integration-test/tl_test/tl_test_rhs_alg_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_rhs_alg_mod.x90 @@ -18,7 +18,7 @@ module tl_test_rhs_alg_mod use function_space_mod, only: function_space_type use derived_config_mod, only: bundle_size use moist_dyn_mod, only: num_moist_factors - use sci_assign_field_random_kernel_mod, only: assign_field_random_kernel_type + use mr_indices_mod, only: nummr use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p use sci_field_bundle_builtins_mod, only: clone_bundle, & add_bundle, & @@ -29,7 +29,9 @@ module tl_test_rhs_alg_mod use tl_rhs_alg_mod, only: tl_rhs_alg use log_mod, only: log_event, LOG_LEVEL_INFO, & LOG_LEVEL_ERROR - use tl_test_convergence_rate_check, only: convergence_rate_check + use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg + use tl_moist_dyn_factors_alg_mod, only: tl_moist_dyn_factors_alg + use tl_test_convergence_rate_check, only: array_convergence_rate_check implicit none @@ -56,8 +58,8 @@ module tl_test_rhs_alg_mod character(str_def) :: label = "rhs_alg" - type(field_collection_type ), pointer :: ls_fields - + type( field_collection_type ), pointer :: ls_fields + type( field_collection_type ), pointer :: prognostic_fields => null() type( field_type ) :: state(bundle_size) type( field_type ) :: ls_state(bundle_size) @@ -73,37 +75,62 @@ module tl_test_rhs_alg_mod type(field_type), pointer :: ls_theta => null() type(field_type), pointer :: ls_exner => null() type(field_type), pointer :: ls_moist_dyn(:) => null() + type(field_type), pointer :: ls_mr(:) => null() + type(field_type), pointer :: u => null() + type(field_type), pointer :: rho => null() + type(field_type), pointer :: theta => null() + type(field_type), pointer :: exner => null() + type(field_type), pointer :: moist_dyn(:) => null() + type(field_type), pointer :: mr(:) => null() type(field_type), dimension(num_moist_factors) :: p_moist_dyn type(field_type), dimension(num_moist_factors) :: n_moist_dyn type(field_type), dimension(num_moist_factors) :: r_moist_dyn type(field_collection_type), pointer :: moisture_fields => null() + type(field_array_type), pointer :: mr_array => null() + type(field_array_type), pointer :: moist_dyn_array => null() + type(field_array_type), pointer :: ls_mr_array => null() type(field_array_type), pointer :: ls_moist_dyn_array => null() real(r_def) :: gamma_u, gamma_rho, gamma_exner, gamma_theta, & gamma_moist_dyn - real(r_def) :: norm_u, norm_rho, norm_exner, norm_theta, norm_moist_dyn - real(r_def) :: norm_moist_dyn_tmp - real(r_def) :: norm_diff, norm_diff_prev + real(r_def) :: norm_u, norm_exner + integer(i_def), parameter :: n_variables = 2 + real(r_def) :: array_norm(n_variables), array_norm_prev(n_variables) + character(str_def) :: array_names(n_variables) - real(r_def), parameter :: tol = 1.e-2_r_def + real(r_def), parameter :: tol = 5.e-2_r_def + real(r_def), parameter :: indiv_tol = 5.e-1_r_def integer :: i, n call log_event( "TL Test: " // trim(label), & LOG_LEVEL_INFO ) + prognostic_fields => modeldb%fields%get_field_collection( & + "prognostic_fields") ls_fields => modeldb%fields%get_field_collection("ls_fields") moisture_fields => modeldb%fields%get_field_collection("moisture_fields") + call moisture_fields%get_field("mr", mr_array) + call moisture_fields%get_field("moist_dyn", moist_dyn_array) + mr => mr_array%bundle + moist_dyn => moist_dyn_array%bundle + call moisture_fields%get_field("ls_mr", ls_mr_array) call moisture_fields%get_field("ls_moist_dyn", ls_moist_dyn_array) + ls_mr => ls_mr_array%bundle ls_moist_dyn => ls_moist_dyn_array%bundle - ! Input + ! Linearisation state call ls_fields%get_field('ls_u', ls_u) call ls_fields%get_field('ls_rho', ls_rho) call ls_fields%get_field('ls_theta', ls_theta) call ls_fields%get_field('ls_exner', ls_exner) + ! Perturbation + call prognostic_fields%get_field('u', u) + call prognostic_fields%get_field('rho', rho) + call prognostic_fields%get_field('theta', theta) + call prognostic_fields%get_field('exner', exner) call ls_state(igh_u)%initialise( vector_space = ls_u%get_function_space() ) call ls_state(igh_t)%initialise( vector_space = ls_theta%get_function_space() ) @@ -127,24 +154,27 @@ module tl_test_rhs_alg_mod setval_X(ls_state(igh_d), ls_rho ), & setval_X(ls_state(igh_p), ls_exner) ) - call invoke( assign_field_random_kernel_type( random(igh_u), 1.0_r_def ) , & - assign_field_random_kernel_type( random(igh_d), 1.0_r_def ) , & - assign_field_random_kernel_type( random(igh_t), 1.0_r_def ) , & - assign_field_random_kernel_type( random(igh_p), 1.0_r_def ) ) + call moist_dyn_factors_alg(ls_moist_dyn, ls_mr) - do i = 1, num_moist_factors - call invoke( assign_field_random_kernel_type( r_moist_dyn(i), 1.0_r_def ) ) - enddo + ! Set the 'random data' to be the perturbation + call invoke( name = "copy_fields_to_state", & + setval_X(random(igh_u), u ), & + setval_X(random(igh_p), exner ), & + setval_X(random(igh_t), theta), & + setval_X(random(igh_d), rho ) ) - gamma_u = 1.e2_r_def - gamma_theta = 1.e2_r_def - gamma_rho = 1.e2_r_def - gamma_exner = 1.e1_r_def - gamma_moist_dyn = 1.e-1_r_def + call tl_moist_dyn_factors_alg(r_moist_dyn, mr ) + + gamma_u = 1.0_r_def + gamma_theta = 1.0_r_def + gamma_rho = 1.0_r_def + gamma_exner = 1.0_r_def + gamma_moist_dyn = 1.0_r_def call set_bundle_scalar( 0.0_r_def, n1_rhs, bundle_size ) call rhs_alg( n1_rhs, dt, ls_state, ls_state, ls_moist_dyn, & - .true., .true., .false., modeldb%clock ) + compute_eos=.true., compute_rhs_t_d=.true., & + dlayer_rhs=.true., model_clock=modeldb%clock ) do n=1,2 gamma_u = gamma_u / 2.0_r_def @@ -166,42 +196,45 @@ module tl_test_rhs_alg_mod do i = 1, num_moist_factors call invoke( & a_times_X( p_moist_dyn(i), gamma_moist_dyn, r_moist_dyn(i) ), & - setval_X( n_moist_dyn(i), ls_moist_dyn(i) ), & + setval_X( n_moist_dyn(i), ls_moist_dyn(i) ), & inc_X_plus_Y( n_moist_dyn(i), p_moist_dyn(i) ) ) enddo call rhs_alg( n2_rhs, dt, state, state, n_moist_dyn, & - .true., .true., .false., modeldb%clock ) + compute_eos=.true., compute_rhs_t_d=.true., & + dlayer_rhs=.true., model_clock=modeldb%clock ) call tl_rhs_alg(p_rhs, dt, p_state, p_state, p_moist_dyn, & ls_state, ls_moist_dyn, & - .true., .false., modeldb%clock) + compute_eos=.true., dlayer_rhs=.true., & + model_clock=modeldb%clock) ! diff = n2_rhs - n1_rhs call minus_bundle( n2_rhs, n1_rhs, diff, bundle_size ) call invoke( & inc_X_minus_Y( diff(igh_u), p_rhs(igh_u) ), & - inc_X_minus_Y( diff(igh_t), p_rhs(igh_t) ), & - inc_X_minus_Y( diff(igh_d), p_rhs(igh_d) ), & inc_X_minus_Y( diff(igh_p), p_rhs(igh_p) ) ) call invoke( X_innerproduct_X( norm_u, diff(igh_u) ) , & - X_innerproduct_X( norm_rho, diff(igh_d) ) , & - X_innerproduct_X( norm_theta, diff(igh_t) ) , & X_innerproduct_X( norm_exner, diff(igh_p) ) ) - print*, norm_u, norm_rho, norm_theta, norm_exner - norm_diff = norm_u + norm_rho + norm_theta + norm_exner - norm_diff = sqrt(norm_diff) - print*,'norm', norm_diff + ! The equations for rho and theta are already linear + ! so only evaluate u and exner + array_norm(1) = norm_u + array_norm(2) = norm_exner + array_names(1) = 'norm_u' + array_names(2) = 'norm_exner' if (n == 2) then - call convergence_rate_check( norm_diff, norm_diff_prev, & - label, tol=tol ) - endif + call array_convergence_rate_check( & + array_norm, array_norm_prev, & + array_names, n_variables, label, tol=tol, & + indiv_tol=indiv_tol ) + end if + + array_norm_prev = array_norm - norm_diff_prev = norm_diff enddo end subroutine test_rhs_alg diff --git a/science/linear/integration-test/tl_test/tl_test_rhs_project_eos_mod.x90 b/science/linear/integration-test/tl_test/tl_test_rhs_project_eos_mod.x90 index 9504122f7..8b39ecb51 100644 --- a/science/linear/integration-test/tl_test/tl_test_rhs_project_eos_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_rhs_project_eos_mod.x90 @@ -209,7 +209,6 @@ contains call invoke( X_minus_Y( diff, n2_rhs, n1_rhs ), & inc_X_minus_Y( diff, p_rhs ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) if (n == 2) then call convergence_rate_check( norm_diff, norm_diff_prev, & diff --git a/science/linear/integration-test/tl_test/tl_test_rhs_sample_eos_mod.x90 b/science/linear/integration-test/tl_test/tl_test_rhs_sample_eos_mod.x90 index 49d69273f..0d1cd26d1 100644 --- a/science/linear/integration-test/tl_test/tl_test_rhs_sample_eos_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_rhs_sample_eos_mod.x90 @@ -195,7 +195,6 @@ contains call invoke( X_minus_Y( diff, n2_rhs, n1_rhs ), & inc_X_minus_Y( diff, p_rhs ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) if (n == 2) then call convergence_rate_check( norm_diff, norm_diff_prev, & diff --git a/science/linear/integration-test/tl_test/tl_test_rk_alg_mod.x90 b/science/linear/integration-test/tl_test/tl_test_rk_alg_mod.x90 index 9b99f0fc8..d16f4c14c 100644 --- a/science/linear/integration-test/tl_test/tl_test_rk_alg_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_rk_alg_mod.x90 @@ -251,6 +251,7 @@ module tl_test_rk_alg_mod ! Evolve the perturbation fields with the linear timestep. This ! gives p_x=L(gamma r_x) + call tl_rk_alg_final() call tl_rk_alg_init(mesh, p_u, p_rho, p_theta, p_exner, & ls_u, ls_rho, ls_theta, ls_exner) @@ -300,7 +301,6 @@ module tl_test_rk_alg_mod call log_event( log_scratch_space, LOG_LEVEL_INFO ) norm_diff = norm_rho + norm_theta + norm_exner + norm_u + norm_moist_dyn - norm_diff = sqrt(norm_diff) if (n == 2) then ! Compare results from first and second iteration diff --git a/science/linear/integration-test/tl_test/tl_test_sample_eos_pressure_mod.x90 b/science/linear/integration-test/tl_test/tl_test_sample_eos_pressure_mod.x90 index b6f56addf..1915214ca 100644 --- a/science/linear/integration-test/tl_test/tl_test_sample_eos_pressure_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_sample_eos_pressure_mod.x90 @@ -175,7 +175,6 @@ module tl_test_sample_eos_pressure_mod call invoke( X_minus_Y( diff, n2_exner, n1_exner ), & inc_X_minus_Y( diff, p_exner ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ', gamma , ' norm = ', norm_diff diff --git a/science/linear/integration-test/tl_test/tl_test_semi_imp_alg_mod.x90 b/science/linear/integration-test/tl_test/tl_test_semi_imp_alg_mod.x90 index 2b060eac1..30bf004ec 100644 --- a/science/linear/integration-test/tl_test/tl_test_semi_imp_alg_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_semi_imp_alg_mod.x90 @@ -10,8 +10,6 @@ !! implicit algorithm, using the Taylor remainder convergence test. module tl_test_semi_imp_alg_mod - use sci_assign_field_random_kernel_mod, & - only: assign_field_random_kernel_type use constants_mod, only: i_def, r_def, str_def use field_array_mod, only: field_array_type use field_mod, only: field_type @@ -39,7 +37,7 @@ module tl_test_semi_imp_alg_mod use timestep_method_mod, only: timestep_method_type use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg use tl_moist_dyn_factors_alg_mod, only: tl_moist_dyn_factors_alg - use tl_test_convergence_rate_check, only: convergence_rate_check + use tl_test_convergence_rate_check, only: array_convergence_rate_check implicit none @@ -128,9 +126,12 @@ module tl_test_semi_imp_alg_mod real(r_def) :: gamma_mr real(r_def) :: norm_u, norm_rho, norm_exner, norm_theta real(r_def) :: norm_mr, norm_mr_tmp - real(r_def) :: norm_diff, norm_diff_prev + integer(i_def), parameter :: n_variables = 5 + real(r_def) :: array_norm(n_variables), array_norm_prev(n_variables) + character(str_def) :: array_names(n_variables) - real(r_def), parameter :: tol = 5.e-1_r_def + real(r_def), parameter :: tol = 5.e-2_r_def + real(r_def), parameter :: indiv_tol = 5.e-1_r_def real(r_def), parameter :: dtemp_encorr = 0.0_r_def integer :: n, i @@ -173,12 +174,14 @@ module tl_test_semi_imp_alg_mod aerosol_fields => modeldb%fields%get_field_collection("aerosol_fields") stph_fields => modeldb%fields%get_field_collection("stph_fields") lbc_fields => modeldb%fields%get_field_collection("lbc_fields") - ! Input + + ! Linearisation State call ls_fields%get_field('ls_u', ls_u) call ls_fields%get_field('ls_rho', ls_rho) call ls_fields%get_field('ls_theta', ls_theta) call ls_fields%get_field('ls_exner', ls_exner) + ! Perturbation call prognostic_fields%get_field('u', u) call prognostic_fields%get_field('rho', rho) call prognostic_fields%get_field('theta', theta) @@ -228,15 +231,29 @@ module tl_test_semi_imp_alg_mod call clone_bundle(mr, b_mr, nummr) call clone_bundle(mr, diff_mr, nummr) - call invoke( assign_field_random_kernel_type( r_u, 1.0_r_def ) , & - assign_field_random_kernel_type( r_rho, 1.0_r_def ) , & - assign_field_random_kernel_type( r_theta, 1.0_r_def ) , & - assign_field_random_kernel_type( r_exner, 1.0_r_def ) ) - + ! Set the 'random data' to be the perturbation + call invoke( name = "copy_fields_to_state", & + setval_X(r_u, u ), & + setval_X(r_exner, exner ), & + setval_X(r_theta, theta), & + setval_X(r_rho, rho ) ) + + ! Overwrite the moisture fields with potential temperature + ! + ! Note: The perturbation fields are read in from file. However the + ! moisture perturbation fields have values close to zero (especially + ! at upper levels) and this gives an inaccurate linearisation test. Using + ! potential temperature is an easy fix to create a realistic 'random' + ! field using real data that has mostly non-zero values. do i = 1, nummr - call invoke( assign_field_random_kernel_type( r_mr(i), 1.0_r_def ) ) + call invoke( & + setval_X( r_mr(i), theta ), & + inc_a_times_X( 0.000001_r_def, r_mr(i) ), & + setval_X( ls_mr(i), ls_theta ), & + inc_a_times_X( 0.000001_r_def, ls_mr(i) )) end do + ! Set the prognostic fields to be the linearisation state call invoke( setval_X( u, ls_u ), & setval_X( theta, ls_theta ), & setval_X( rho, ls_rho ), & @@ -247,7 +264,9 @@ module tl_test_semi_imp_alg_mod end do do i = 1, nummr call invoke( setval_X( mr(i), ls_mr(i) ) ) - end do + end do + + call moist_dyn_factors_alg(moist_dyn, mr) ! Clean up solvers left over from previous tests, as semi-implicit ! method will create new solvers which cause double-allocates @@ -274,15 +293,15 @@ module tl_test_semi_imp_alg_mod call invoke( setval_X( b_mr(i), mr(i) ) ) end do - gamma_u = 1.e4_r_def - gamma_theta = 1.e2_r_def - gamma_rho = 8.0e-1_r_def - gamma_exner = 6.5e-1_r_def + gamma_u = 6.5_r_def + gamma_theta = 6.5_r_def + gamma_rho = 6.5_r_def + gamma_exner = 6.5_r_def if ( moisture_formulation == moisture_formulation_dry ) then gamma_mr = 0.0_r_def else - gamma_mr = 1.e-2_r_def + gamma_mr = 6.5_r_def end if do n=1,2 @@ -328,6 +347,8 @@ module tl_test_semi_imp_alg_mod ! Evolve the perturbation fields with the linear timestep. This ! gives p_x=L(gamma r_x) + call final_si_operators() + call tl_semi_implicit_alg_final() call tl_semi_implicit_alg_init(mesh, p_u, p_rho, p_theta, p_exner, & p_mr, ls_u, ls_rho, ls_theta, ls_exner, & ls_mr, ls_moist_dyn) @@ -365,35 +386,24 @@ module tl_test_semi_imp_alg_mod norm_mr = norm_mr + norm_mr_tmp end do - write( log_scratch_space, & - '(A, E32.12, A, E32.12 )' ) & - ' norm_u = ' , norm_u, & - ' norm_rho = ' , norm_rho - - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - write( log_scratch_space, & - '(A, E32.12, A, E32.12 )' ) & - ' norm_mr = ' , norm_mr, & - ' norm_exner = ' , norm_exner - - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - write( log_scratch_space, & - '(A, E32.12 )' ) & - ' norm_theta = ' , norm_theta - - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - norm_diff = norm_rho + norm_theta + norm_exner + norm_u + norm_mr - norm_diff = sqrt(norm_diff) + array_norm(1) = norm_u + array_norm(2) = norm_rho + array_norm(3) = norm_theta + array_norm(4) = norm_mr + array_norm(5) = norm_exner + array_names(1) = 'norm_u' + array_names(2) = 'norm_rho' + array_names(3) = 'norm_theta' + array_names(4) = 'norm_mr' + array_names(5) = 'norm_exner' if (n == 2) then - call convergence_rate_check( norm_diff, norm_diff_prev, & - label, tol=tol ) + call array_convergence_rate_check( array_norm, array_norm_prev, & + array_names, n_variables, label, tol=tol, indiv_tol=indiv_tol ) end if - norm_diff_prev = norm_diff + array_norm_prev = array_norm + end do end subroutine test_semi_imp_alg diff --git a/science/linear/integration-test/tl_test/tl_test_timesteps_alg_mod.x90 b/science/linear/integration-test/tl_test/tl_test_timesteps_alg_mod.x90 index 65759abf9..686e0cad9 100644 --- a/science/linear/integration-test/tl_test/tl_test_timesteps_alg_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_timesteps_alg_mod.x90 @@ -44,7 +44,7 @@ module tl_test_timesteps_alg_mod method, & method_rk use time_config_mod, only: timestep_start, timestep_end - use tl_test_convergence_rate_check, only: convergence_rate_check + use tl_test_convergence_rate_check, only: array_convergence_rate_check use validity_test_config_mod, only: number_gamma_values, & update_ls_frequency use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg @@ -52,7 +52,6 @@ module tl_test_timesteps_alg_mod implicit none - private convergence_pass_string public test_timesteps contains @@ -120,8 +119,12 @@ module tl_test_timesteps_alg_mod real(r_def) :: denom_u, denom_rho, denom_exner, denom_theta, denom_mr real(r_def) :: denom_mr_tmp real(r_def) :: denom_total + integer(i_def), parameter :: n_variables = 5 + real(r_def) :: array_norm(n_variables), array_norm_prev(n_variables) + character(str_def) :: array_names(n_variables) - real(r_def), parameter :: tol = 9.e-1_r_def + real(r_def), parameter :: tol = 3.e-1_r_def + real(r_def), parameter :: indiv_tol = 1.2_r_def integer(i_def) :: n, i, t character(len=4) :: pass_str @@ -212,24 +215,32 @@ module tl_test_timesteps_alg_mod function_space_collection%get_fs(mesh, element_order_h, element_order_v, Wtheta) ) call clone_bundle(mr, diff_mr, nummr) - call invoke( assign_field_random_kernel_type( r_u, 1.0_r_def ) , & - assign_field_random_kernel_type( r_rho, 1.0_r_def ) , & - assign_field_random_kernel_type( r_theta, 1.0_r_def ) , & - assign_field_random_kernel_type( r_exner, 1.0_r_def ) ) + ! Set the 'random data' to be the perturbation + call invoke( name = "copy_fields_to_state", & + setval_X(r_u, u ), & + setval_X(r_exner, exner ), & + setval_X(r_theta, theta), & + setval_X(r_rho, rho ) ) + ! Overwrite the moisture fields with potential temperature do i = 1, nummr - call invoke( assign_field_random_kernel_type( r_mr(i), 1.0_r_def ) ) + call invoke( & + setval_X( r_mr(i), theta ), & + inc_a_times_X( 0.000001_r_def, r_mr(i) ), & + setval_X( ls_mr(i), ls_theta ), & + inc_a_times_X( 0.000001_r_def, ls_mr(i) )) end do + call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) - gamma_u = 1.e4_r_def - gamma_theta = 1.e2_r_def - gamma_rho = 1.e0_r_def - gamma_exner = 6.5e-1_r_def + gamma_u = 6.5_r_def + gamma_theta = 6.5_r_def + gamma_rho = 6.5_r_def + gamma_exner = 6.5_r_def - if ( use_moisture ) then - gamma_mr = 1.e-1_r_def + if ( use_moisture ) then + gamma_mr = 6.5_r_def else - gamma_mr = 0.0_r_def + gamma_mr = 0._r_def end if do n = 1, number_gamma_values @@ -277,6 +288,10 @@ module tl_test_timesteps_alg_mod !------------------------------------------------------------------------ ! Nonlinear model run with perturbed state !------------------------------------------------------------------------ + write(log_scratch_space,'(A, I2)') & + "Perturbed Nonlinear, timestep: ", t + call log_event(log_scratch_space, LOG_LEVEL_INFO) + call invoke( setval_X( u, n1_u ), & setval_X( theta, n1_theta ), & setval_X( rho, n1_rho ), & @@ -314,6 +329,10 @@ module tl_test_timesteps_alg_mod !------------------------------------------------------------------------ ! Linear model run !------------------------------------------------------------------------ + write(log_scratch_space,'(A, I2)') & + "Linear, timestep: ", t + call log_event(log_scratch_space, LOG_LEVEL_INFO) + call invoke( setval_X( u, p_u ), & setval_X( theta, p_theta ), & setval_X( rho, p_rho ), & @@ -337,6 +356,7 @@ module tl_test_timesteps_alg_mod call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) endif + call finalise_linear_model() call initialise_linear_model( mesh, & modeldb ) @@ -359,6 +379,10 @@ module tl_test_timesteps_alg_mod !------------------------------------------------------------------------ ! Nonlinear model run with un-perturbed state !------------------------------------------------------------------------ + write(log_scratch_space,'(A, I2)') & + "Unperturbed NonLinear, timestep: ", t + call log_event(log_scratch_space, LOG_LEVEL_INFO) + call invoke( setval_X( u, n2_u ), & setval_X( theta, n2_theta ), & setval_X( rho, n2_rho ), & @@ -386,6 +410,10 @@ module tl_test_timesteps_alg_mod setval_X( n2_rho, rho ), & setval_X( n2_exner, exner ) ) + do i = 1, nummr + call invoke( setval_X( n2_mr(i), mr(i) ) ) + end do + do i = 1, nummr call invoke( setval_X( ls_mr(i), mr(i) ) ) end do @@ -417,160 +445,67 @@ module tl_test_timesteps_alg_mod norm_mr = norm_mr + norm_mr_tmp end do - norm_diff = norm_rho + norm_theta + norm_exner + norm_u + norm_mr - norm_diff = sqrt( norm_diff ) - norm_u = sqrt( norm_u ) - norm_rho= sqrt( norm_rho ) - norm_theta = sqrt( norm_theta ) - norm_exner = sqrt( norm_exner ) - norm_mr = sqrt( norm_mr ) - - call invoke( X_innerproduct_X( denom_u, p_u ) ) - call invoke( X_innerproduct_X( denom_rho, p_rho ) ) - call invoke( X_innerproduct_X( denom_exner, p_exner ) ) - call invoke( X_innerproduct_X( denom_theta, p_theta ) ) + array_norm(1) = norm_u + array_norm(2) = norm_rho + array_norm(3) = norm_theta + array_norm(4) = norm_mr + array_norm(5) = norm_exner + array_names(1) = 'norm_u' + array_names(2) = 'norm_rho' + array_names(3) = 'norm_theta' + array_names(4) = 'norm_mr' + array_names(5) = 'norm_exner' - denom_mr=0.0_r_def - do i = 1, nummr - call invoke( & - X_innerproduct_X( denom_mr_tmp, p_mr(i) ) ) - denom_mr = denom_mr + denom_mr_tmp - end do + if (n == 2) then + call array_convergence_rate_check( array_norm, array_norm_prev, & + array_names, n_variables, label, tol=tol, indiv_tol=indiv_tol ) + end if - denom_total = denom_rho + denom_theta + denom_exner + denom_u + denom_mr - denom_total = sqrt( denom_total ) - denom_u = sqrt( denom_u ) - denom_rho = sqrt( denom_rho ) - denom_theta = sqrt( denom_theta ) - denom_exner = sqrt( denom_exner ) - denom_mr = sqrt( denom_mr ) + array_norm_prev = array_norm !---------------------------------------------------------------------------- ! Print values out to enable plotting a graph !---------------------------------------------------------------------------- - write( log_scratch_space, & - '( A, E32.12, A, E32.12 )' ) & - ' gamma_total = ' , gamma_u, & - ' norm = ' , norm_diff / denom_total - - call log_event( log_scratch_space, LOG_LEVEL_INFO ) write( log_scratch_space, & '(A, E32.12, A, E32.12)' ) & - ' gamma_rho = ' , gamma_u, & - ' norm = ' , norm_rho / denom_rho + ' gamma_rho = ' , gamma_rho, & + ' norm = ' , norm_rho call log_event( log_scratch_space, LOG_LEVEL_INFO ) write( log_scratch_space, & '(A, E32.12, A, E32.12)' ) & - ' gamma_exner = ' , gamma_u, & - ' norm = ' , norm_exner / denom_exner + ' gamma_exner = ' , gamma_exner, & + ' norm = ' , norm_exner call log_event( log_scratch_space, LOG_LEVEL_INFO ) write( log_scratch_space, & '(A, E32.12, A, E32.12)' ) & - ' gamma_theta = ' , gamma_u, & - ' norm = ' , norm_theta / denom_theta + ' gamma_theta = ' , gamma_theta, & + ' norm = ' , norm_theta call log_event( log_scratch_space, LOG_LEVEL_INFO ) write( log_scratch_space, & '(A, E32.12, A, E32.12)' ) & ' gamma_u = ' , gamma_u, & - ' norm = ' , norm_u / denom_u + ' norm = ' , norm_u call log_event( log_scratch_space, LOG_LEVEL_INFO ) write( log_scratch_space, & '(A, E32.12, A, E32.12)' ) & - ' gamma_mr = ' , gamma_u, & - ' norm = ' , norm_mr / denom_mr + ' gamma_mr = ' , gamma_mr, & + ' norm = ' , norm_mr call log_event( log_scratch_space, LOG_LEVEL_INFO ) -!---------------------------------------------------------------------------- -! Test that gives a PASS or FAIL -!---------------------------------------------------------------------------- - if (n == 2) then - - pass_str = "PASS" - - write( log_scratch_space, '(A)' ) & - "TL Test: " // trim(label) - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - write( log_scratch_space, '(A)' ) "Total " - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - call convergence_pass_string( norm_diff, norm_diff_prev, pass_str, tol ) - - write( log_scratch_space, '(A)' ) "Theta " - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - call convergence_pass_string( norm_theta, norm_theta_prev, pass_str, tol ) - - write( log_scratch_space, '(A)' ) "Rho " - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - call convergence_pass_string( norm_rho, norm_rho_prev, pass_str, tol ) - - write( log_scratch_space, '(A)' ) "Exner " - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - call convergence_pass_string( norm_exner, norm_exner_prev, pass_str, tol ) - - write( log_scratch_space, '(A)' ) "u " - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - call convergence_pass_string( norm_u, norm_u_prev, pass_str, tol ) - - if ( use_moisture ) then - write( log_scratch_space, '(A)' ) "mr " - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - call convergence_pass_string( norm_mr, norm_mr_prev, pass_str, tol ) - end if - - write( log_scratch_space,'(" test",A32," : ",A4)' ) trim(label), pass_str - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - end if - - norm_diff_prev = norm_diff - norm_rho_prev = norm_rho - norm_theta_prev = norm_theta - norm_exner_prev = norm_exner - norm_u_prev = norm_u - norm_mr_prev = norm_mr - end do ! Loop over values of gamma end subroutine test_timesteps - !> @brief Test the convergence rate. - !> @details If the convergence rate is not close to 4, within the - !! specified tolerance, then change the pass string to FAIL. - !> @param[in] norm_diff Current norm - !> @param[in] norm_diff_prev Previous norm - !> @param[inout] pass_str Pass string (either PASS or FAIL) - !> @param[in] tol Test Tolerance - subroutine convergence_pass_string( norm_diff, norm_diff_prev, pass_str, tol ) - implicit none - - real(r_def), intent(in) :: norm_diff, norm_diff_prev - character(len=4), intent(inout) :: pass_str - real(r_def), intent(in) :: tol - - real(r_def) :: conv_rate - conv_rate = norm_diff_prev / norm_diff - - conv_rate = norm_diff_prev / norm_diff - write( log_scratch_space, '(A, E16.8)') & - "Convergence rate: ", conv_rate - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - if ( abs( conv_rate - 4.0_r_def ) >= tol ) then - pass_str = "FAIL" - endif - - end subroutine convergence_pass_string - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !> Converts a string to a timestep number. !> diff --git a/science/linear/integration-test/tl_test/tl_test_timesteps_random_alg_mod.x90 b/science/linear/integration-test/tl_test/tl_test_timesteps_random_alg_mod.x90 new file mode 100644 index 000000000..6ea6ff295 --- /dev/null +++ b/science/linear/integration-test/tl_test/tl_test_timesteps_random_alg_mod.x90 @@ -0,0 +1,597 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- + +!>@brief The tangent linear test for multiple timesteps +!! (Taylor remainder convergence). +!>@details Test whether the tangent linear code is tangent linear +!! to the corresponding nonlinear code, for multiple timesteps, +!! using the Taylor remainder convergence test. +module tl_test_timesteps_random_alg_mod + use sci_assign_field_random_kernel_mod, & + only: assign_field_random_kernel_type + use constants_mod, only: i_timestep, i_def, r_def, l_def, & + str_def + use field_array_mod, only: field_array_type + use field_mod, only: field_type + use sci_field_bundle_builtins_mod, only: clone_bundle + use field_collection_mod, only: field_collection_type + use finite_element_config_mod, only: element_order_h, element_order_v + use formulation_config_mod, only: moisture_formulation, & + moisture_formulation_dry + use fs_continuity_mod, only: W2, W3, Wtheta + use function_space_collection_mod, only: function_space_collection + use gungho_step_mod, only: gungho_step + use gungho_model_mod, only: initialise_model, & + finalise_model + use driver_modeldb_mod, only: modeldb_type + use log_mod, only: log_event, & + log_scratch_space, & + LOG_LEVEL_INFO, & + LOG_LEVEL_ERROR + use linear_step_mod, only: linear_step + use linear_model_mod, only: initialise_linear_model, & + finalise_linear_model + use mesh_mod, only: mesh_type + use model_clock_mod, only: model_clock_type + use moist_dyn_mod, only: num_moist_factors + use mr_indices_mod, only: nummr + use semi_implicit_solver_alg_mod, only: semi_implicit_solver_alg_final + use si_operators_alg_mod, only: final_si_operators + use timestepping_config_mod, only: dt, & + method, & + method_rk + use time_config_mod, only: timestep_start, timestep_end + use tl_test_convergence_rate_check, only: convergence_rate_check + use validity_test_config_mod, only: number_gamma_values, & + update_ls_frequency + use moist_dyn_factors_alg_mod, only: moist_dyn_factors_alg + use tl_moist_dyn_factors_alg_mod, only: tl_moist_dyn_factors_alg + + implicit none + + private convergence_pass_string + public test_timesteps_random + + contains + + !> @brief Test the tangent linear runge-kutta algorithm. + !> @param[in] modeldb The working data set for a model run + !> @param[in] mesh The current 3d mesh + !> @param[in] twod_mesh The current 2d mesh + !> @param[in] model_clock Time within the model. + !> + subroutine test_timesteps_random( modeldb, & + mesh, & + twod_mesh, & + model_clock ) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(mesh_type), pointer, intent(in) :: mesh + type(mesh_type), pointer, intent(in) :: twod_mesh + class(model_clock_type), intent(in) :: model_clock + + character(str_def) :: label = "timesteps" + + type(field_collection_type), pointer :: prognostic_fields + type(field_collection_type), pointer :: ls_fields + + type(field_type), pointer :: ls_u + type(field_type), pointer :: ls_rho + type(field_type), pointer :: ls_theta + type(field_type), pointer :: ls_exner + type(field_type), pointer :: ls_moist_dyn(:) + type(field_type), pointer :: ls_mr(:) + + type(field_type), pointer :: u + type(field_type), pointer :: rho + type(field_type), pointer :: theta + type(field_type), pointer :: exner + type(field_type), pointer :: moist_dyn(:) + type(field_type), pointer :: mr(:) + + type(field_type), dimension(nummr) :: p_mr + type(field_type), dimension(nummr) :: n1_mr + type(field_type), dimension(nummr) :: n2_mr + type(field_type), dimension(nummr) :: r_mr + type(field_type), dimension(nummr) :: diff_mr + type(field_type) :: p_u, p_rho, p_theta, p_exner + type(field_type) :: n1_u, n1_rho, n1_theta, n1_exner + type(field_type) :: n2_u, n2_rho, n2_theta, n2_exner + type(field_type) :: r_u, r_rho, r_theta, r_exner + type(field_type) :: diff_u, diff_rho, diff_theta, diff_exner + + type(field_collection_type), pointer :: moisture_fields + type(field_array_type), pointer :: mr_array + type(field_array_type), pointer :: moist_dyn_array + type(field_array_type), pointer :: ls_mr_array + type(field_array_type), pointer :: ls_moist_dyn_array + + real(r_def) :: gamma_u, gamma_rho, gamma_exner, gamma_theta, gamma_mr + real(r_def) :: norm_u, norm_rho, norm_exner, norm_theta, norm_mr + real(r_def) :: norm_mr_tmp + real(r_def) :: norm_diff, norm_diff_prev + real(r_def) :: norm_u_prev, norm_rho_prev, norm_exner_prev + real(r_def) :: norm_theta_prev, norm_mr_prev + + real(r_def), parameter :: tol = 9.e-1_r_def + + integer(i_def) :: n, i, t + character(len=4) :: pass_str + logical(l_def) :: use_moisture + + call log_event( "TL Test: " // trim(label), & + LOG_LEVEL_INFO ) + + use_moisture = ( moisture_formulation /= moisture_formulation_dry ) + + if ( method == method_rk .and. use_moisture ) then + call log_event( & + 'Not possible to use Runge Kutta time stepping with moisture', & + log_level_error ) + end if + + prognostic_fields => modeldb%fields%get_field_collection( & + "prognostic_fields") + ls_fields => modeldb%fields%get_field_collection("ls_fields") + moisture_fields => modeldb%fields%get_field_collection("moisture_fields") + call moisture_fields%get_field("mr", mr_array) + call moisture_fields%get_field("moist_dyn", moist_dyn_array) + mr => mr_array%bundle + moist_dyn => moist_dyn_array%bundle + call moisture_fields%get_field("ls_mr", ls_mr_array) + call moisture_fields%get_field("ls_moist_dyn", ls_moist_dyn_array) + ls_mr => ls_mr_array%bundle + ls_moist_dyn => ls_moist_dyn_array%bundle + + ! Input + call ls_fields%get_field('ls_u', ls_u) + call ls_fields%get_field('ls_rho', ls_rho) + call ls_fields%get_field('ls_theta', ls_theta) + call ls_fields%get_field('ls_exner', ls_exner) + + call prognostic_fields%get_field('u', u) + call prognostic_fields%get_field('rho', rho) + call prognostic_fields%get_field('theta', theta) + call prognostic_fields%get_field('exner', exner) + + call r_u%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W2) ) + call r_rho%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call r_exner%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call r_theta%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, Wtheta) ) + call clone_bundle(mr, r_mr, nummr) + + call p_u%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W2) ) + call p_rho%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call p_exner%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call p_theta%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, Wtheta) ) + call clone_bundle(mr, p_mr, nummr) + + call n1_u%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W2) ) + call n1_rho%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call n1_exner%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call n1_theta%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, Wtheta) ) + call clone_bundle(mr, n1_mr, nummr) + + call n2_u%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W2) ) + call n2_rho%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call n2_exner%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call n2_theta%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, Wtheta) ) + call clone_bundle(mr, n2_mr, nummr) + + call diff_u%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W2) ) + call diff_rho%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call diff_exner%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, W3) ) + call diff_theta%initialise( vector_space = & + function_space_collection%get_fs(mesh, element_order_h, element_order_v, Wtheta) ) + call clone_bundle(mr, diff_mr, nummr) + + call invoke( assign_field_random_kernel_type( r_u, 1.0_r_def ) , & + assign_field_random_kernel_type( r_rho, 1.0_r_def ) , & + assign_field_random_kernel_type( r_theta, 1.0_r_def ) , & + assign_field_random_kernel_type( r_exner, 1.0_r_def ) ) + + do i = 1, nummr + call invoke( assign_field_random_kernel_type( r_mr(i), 1.0_r_def ) ) + end do + + gamma_u = 1.e4_r_def + gamma_theta = 1.0_r_def + gamma_rho = 1.e0_r_def + gamma_exner = 6.5e-1_r_def + + if ( use_moisture ) then + gamma_mr = 1.e-3_r_def + else + gamma_mr = 0.0_r_def + end if + + gamma_u = gamma_u /24.0_r_def + gamma_theta = gamma_theta / 24.0_r_def + gamma_rho = gamma_rho / 24.0_r_def + gamma_exner = gamma_exner / 24.0_r_def + gamma_mr = gamma_mr / 24.0_r_def + + do n = 1, number_gamma_values + gamma_u = gamma_u / 2.0_r_def + gamma_theta = gamma_theta / 2.0_r_def + gamma_rho = gamma_rho / 2.0_r_def + gamma_exner = gamma_exner / 2.0_r_def + gamma_mr = gamma_mr / 2.0_r_def + + ! Initial conditions for nonlinear perturbed + call invoke( aX_plus_Y( n1_u, gamma_u, r_u, ls_u ), & + aX_plus_Y( n1_theta, gamma_theta, r_theta, ls_theta ), & + aX_plus_Y( n1_rho, gamma_rho, r_rho, ls_rho ), & + aX_plus_Y( n1_exner, gamma_exner, r_exner, ls_exner ) ) + + do i = 1, nummr + call invoke( aX_plus_Y( n1_mr(i), gamma_mr, & + r_mr(i), ls_mr(i) ) ) + end do + + ! Initial conditions for nonlinear unperturbed + call invoke( setval_X( n2_u, ls_u ), & + setval_X( n2_theta, ls_theta ), & + setval_X( n2_rho, ls_rho ), & + setval_X( n2_exner, ls_exner ) ) + + do i = 1, nummr + call invoke( setval_X( n2_mr(i), ls_mr(i) ) ) + end do + + ! Initial conditions for the linear + call invoke( a_times_X( p_u, gamma_u, r_u ), & + a_times_X( p_theta, gamma_theta, r_theta ), & + a_times_X( p_rho, gamma_rho, r_rho ), & + a_times_X( p_exner, gamma_exner, r_exner ) ) + + do i = 1, nummr + call invoke( a_times_X( p_mr(i), gamma_mr, & + r_mr(i) ) ) + end do + + ! Multiple timesteps + do t = parse_instance(timestep_start), parse_instance(timestep_end) + +!------------------------------------------------------------------------ +! Nonlinear model run with perturbed state +!------------------------------------------------------------------------ + call invoke( setval_X( u, n1_u ), & + setval_X( theta, n1_theta ), & + setval_X( rho, n1_rho ), & + setval_X( exner, n1_exner ) ) + do i = 1, nummr + call invoke( setval_X( mr(i), n1_mr(i) ) ) + enddo + call moist_dyn_factors_alg( moist_dyn, mr ) + + ! Clean up solvers and timestep method left over from running + ! the model to set up model state and linear state + call final_si_operators() + call semi_implicit_solver_alg_final() + call finalise_model(modeldb) + + call initialise_model( mesh, & + modeldb ) + + call gungho_step( mesh, & + twod_mesh, & + modeldb, & + model_clock ) + + call finalise_model(modeldb) + + call invoke( setval_X( n1_u, u ), & + setval_X( n1_theta, theta ), & + setval_X( n1_rho, rho ), & + setval_X( n1_exner, exner) ) + + do i = 1, nummr + call invoke( setval_X( n1_mr(i), mr(i) ) ) + end do + +!------------------------------------------------------------------------ +! Linear model run +!------------------------------------------------------------------------ + call invoke( setval_X( u, p_u ), & + setval_X( theta, p_theta ), & + setval_X( rho, p_rho ), & + setval_X( exner, p_exner) ) + do i = 1, nummr + call invoke( setval_X( mr(i), p_mr(i) ) ) + end do + call tl_moist_dyn_factors_alg( moist_dyn, mr ) + + ! Set the linearisation state + ! The linearisation state is copied from the nonlinear run, + ! every few timesteps. + if ( mod(t, update_ls_frequency) == 0 ) then + call invoke( setval_X( ls_u, n2_u ), & + setval_X( ls_theta, n2_theta ), & + setval_X( ls_rho, n2_rho ), & + setval_X( ls_exner, n2_exner) ) + do i = 1, nummr + call invoke( setval_X( ls_mr(i), n2_mr(i) ) ) + enddo + call moist_dyn_factors_alg( ls_moist_dyn, ls_mr ) + endif + + call finalise_linear_model() + call initialise_linear_model( mesh, & + modeldb ) + + call linear_step( mesh, & + twod_mesh, & + modeldb, & + model_clock ) + + call finalise_linear_model() + + + call invoke( setval_X( p_u, u ), & + setval_X( p_theta, theta ), & + setval_X( p_rho, rho ), & + setval_X( p_exner, exner) ) + do i = 1, nummr + call invoke( setval_X( p_mr(i), mr(i) ) ) + enddo + +!------------------------------------------------------------------------ +! Nonlinear model run with un-perturbed state +!------------------------------------------------------------------------ + call invoke( setval_X( u, n2_u ), & + setval_X( theta, n2_theta ), & + setval_X( rho, n2_rho ), & + setval_X( exner, n2_exner ) ) + + do i = 1, nummr + call invoke( setval_X( mr(i), n2_mr(i) ) ) + end do + + call moist_dyn_factors_alg( moist_dyn, mr ) + + + call initialise_model( mesh, & + modeldb ) + + call gungho_step( mesh, & + twod_mesh, & + modeldb, & + model_clock ) + + call finalise_model(modeldb) + + call invoke( setval_X( n2_u, u ), & + setval_X( n2_theta, theta ), & + setval_X( n2_rho, rho ), & + setval_X( n2_exner, exner ) ) + + do i = 1, nummr + call invoke( setval_X( n2_mr(i), mr(i) ) ) + call invoke( setval_X( ls_mr(i), mr(i) ) ) + end do + + end do ! timesteps loop + +!------------------------------------------------------------------------ +! Calculate norms +!------------------------------------------------------------------------ + call invoke( X_minus_Y( diff_u, n1_u, n2_u ), & + inc_X_minus_Y( diff_u, p_u ), & + X_innerproduct_X( norm_u, diff_u ) ) + call invoke( X_minus_Y( diff_rho, n1_rho, n2_rho ), & + inc_X_minus_Y( diff_rho, p_rho ), & + X_innerproduct_X( norm_rho, diff_rho ) ) + call invoke( X_minus_Y( diff_exner, n1_exner, n2_exner ), & + inc_X_minus_Y( diff_exner, p_exner ), & + X_innerproduct_X( norm_exner, diff_exner ) ) + call invoke( X_minus_Y( diff_theta, n1_theta, n2_theta ), & + inc_X_minus_Y( diff_theta, p_theta ), & + X_innerproduct_X( norm_theta, diff_theta ) ) + + norm_mr=0.0_r_def + do i = 1, nummr + call invoke( & + X_minus_Y( diff_mr(i), n1_mr(i), n2_mr(i) ), & + inc_X_minus_Y( diff_mr(i), p_mr(i) ), & + X_innerproduct_X( norm_mr_tmp, diff_mr(i) ) ) + norm_mr = norm_mr + norm_mr_tmp + end do + + norm_diff = norm_rho + norm_theta + norm_exner + norm_u + norm_mr + +!---------------------------------------------------------------------------- +! Print values out to enable plotting a graph +!---------------------------------------------------------------------------- + write( log_scratch_space, & + '( A, E32.12, A, E32.12 )' ) & + ' gamma_total = ' , gamma_u, & + ' norm = ' , norm_diff + + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + write( log_scratch_space, & + '(A, E32.12, A, E32.12)' ) & + ' gamma_rho = ' , gamma_u, & + ' norm = ' , norm_rho + + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + write( log_scratch_space, & + '(A, E32.12, A, E32.12)' ) & + ' gamma_exner = ' , gamma_u, & + ' norm = ' , norm_exner + + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + write( log_scratch_space, & + '(A, E32.12, A, E32.12)' ) & + ' gamma_theta = ' , gamma_u, & + ' norm = ' , norm_theta + + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + write( log_scratch_space, & + '(A, E32.12, A, E32.12)' ) & + ' gamma_u = ' , gamma_u, & + ' norm = ' , norm_u + + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + write( log_scratch_space, & + '(A, E32.12, A, E32.12)' ) & + ' gamma_mr = ' , gamma_u, & + ' norm = ' , norm_mr + + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + +!---------------------------------------------------------------------------- +! Test that gives a PASS or FAIL +!---------------------------------------------------------------------------- + if (n == 2) then + + pass_str = "PASS" + + write( log_scratch_space, '(A)' ) & + "TL Test: " // trim(label) + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + write( log_scratch_space, '(A)' ) "Total " + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call convergence_pass_string( norm_diff, norm_diff_prev, pass_str, tol ) + + write( log_scratch_space, '(A)' ) "Theta " + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call convergence_pass_string( norm_theta, norm_theta_prev, pass_str, tol ) + + write( log_scratch_space, '(A)' ) "Rho " + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call convergence_pass_string( norm_rho, norm_rho_prev, pass_str, tol ) + + write( log_scratch_space, '(A)' ) "Exner " + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call convergence_pass_string( norm_exner, norm_exner_prev, pass_str, tol ) + + write( log_scratch_space, '(A)' ) "u " + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call convergence_pass_string( norm_u, norm_u_prev, pass_str, tol ) + + if ( use_moisture ) then + write( log_scratch_space, '(A)' ) "mr " + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + call convergence_pass_string( norm_mr, norm_mr_prev, pass_str, tol ) + end if + + write( log_scratch_space,'(" test",A32," : ",A4)' ) trim(label), pass_str + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + end if + + norm_diff_prev = norm_diff + norm_rho_prev = norm_rho + norm_theta_prev = norm_theta + norm_exner_prev = norm_exner + norm_u_prev = norm_u + norm_mr_prev = norm_mr + + end do ! Loop over values of gamma + + end subroutine test_timesteps_random + + !> @brief Test the convergence rate. + !> @details If the convergence rate is not close to 4, within the + !! specified tolerance, then change the pass string to FAIL. + !! This is a special routine for this particular test, to allow + !! for norms that have already had the square root applied. + !> @param[in] norm_diff Current norm + !> @param[in] norm_diff_prev Previous norm + !> @param[inout] pass_str Pass string (either PASS or FAIL) + !> @param[in] tol Test Tolerance + subroutine convergence_pass_string( norm_diff, norm_diff_prev, pass_str, tol ) + implicit none + + real(r_def), intent(in) :: norm_diff, norm_diff_prev + character(len=4), intent(inout) :: pass_str + real(r_def), intent(in) :: tol + + real(r_def) :: conv_rate + conv_rate = norm_diff_prev / norm_diff + + conv_rate = norm_diff_prev / norm_diff + write( log_scratch_space, '(A, E16.8)') & + "Convergence rate: ", conv_rate + call log_event( log_scratch_space, LOG_LEVEL_INFO ) + + if ( abs( conv_rate - 4.0_r_def ) >= tol ) then + pass_str = "FAIL" + endif + + end subroutine convergence_pass_string + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !> Converts a string to a timestep number. + !> + !> @param[in] string Correctly formatted timestep number. + !> @return Timestep number. + !> + function parse_instance( string ) result(instance) + + implicit none + + character(*), intent(in) :: string + integer(i_timestep) :: instance + + integer :: string_size + integer :: format_size + integer :: status + character(:), allocatable :: fmt + + ! The "I0" formatting string does not work for input. Instead the exact + ! number of digits to be read must be requested. Thus we need to construct + ! a format string from the size of the string. + ! + string_size = len(string) + format_size = string_size + 3 + allocate( character(format_size) :: fmt, stat=status ) + if ( status /= 0 ) then + call log_event( & + 'TL test parse_instance: Unable to allocate format', & + log_level_error ) + end if + write( fmt, '("(I", I0, ")")' ) string_size + read( string, fmt ) instance + deallocate( fmt ) + + if ( instance < 0 ) then + call log_event( & + 'TL test parse_instance: Instances may not be negative', & + log_level_error ) + end if + + end function parse_instance + +end module tl_test_timesteps_random_alg_mod diff --git a/science/linear/integration-test/tl_test/tl_test_transport_control_mod.x90 b/science/linear/integration-test/tl_test/tl_test_transport_control_mod.x90 index 02d96d2ea..d74fd3dfb 100644 --- a/science/linear/integration-test/tl_test/tl_test_transport_control_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_transport_control_mod.x90 @@ -21,7 +21,6 @@ module tl_test_transport_control_mod use function_space_collection_mod, only: function_space_collection use derived_config_mod, only: bundle_size use driver_modeldb_mod, only: modeldb_type - use moist_dyn_mod, only: num_moist_factors use mr_indices_mod, only: nummr use log_mod, only: log_event, & log_scratch_space, & @@ -31,7 +30,7 @@ module tl_test_transport_control_mod only: gungho_transport_control_alg_init, & gungho_transport_control_alg use tl_transport_control_alg_mod, only: tl_transport_control_alg - use tl_test_convergence_rate_check, only: convergence_rate_check + use tl_test_convergence_rate_check, only: array_convergence_rate_check implicit none @@ -61,10 +60,11 @@ module tl_test_transport_control_mod type(field_type), pointer :: ls_u => null() type(field_type), pointer :: ls_rho => null() type(field_type), pointer :: ls_theta => null() - type(field_type), pointer :: ls_exner => null() - type(field_type), pointer :: ls_moist_dyn(:) => null() type(field_type), pointer :: ls_mr(:) => null() - type(field_type), pointer :: moist_dyn(:) => null() + type(field_type), pointer :: ls_exner => null() + type(field_type), pointer :: u => null() + type(field_type), pointer :: rho => null() + type(field_type), pointer :: theta => null() type(field_type), pointer :: mr(:) => null() type(field_type) :: state(bundle_size) @@ -75,10 +75,7 @@ module tl_test_transport_control_mod type(field_type) :: n1_rhs(bundle_size) type(field_type) :: n2_rhs(bundle_size) type(field_type) :: diff(bundle_size) - type(field_type), dimension(num_moist_factors) :: p_moist_dyn - type(field_type), dimension(num_moist_factors) :: n_moist_dyn - type(field_type), dimension(num_moist_factors) :: r_moist_dyn - type(field_type), dimension(num_moist_factors) :: diff_moist_dyn + type(field_type), dimension(nummr) :: p_mr_in type(field_type), dimension(nummr) :: n_mr_in type(field_type), dimension(nummr) :: ls_mr_out @@ -91,36 +88,32 @@ module tl_test_transport_control_mod type(field_collection_type), pointer :: moisture_fields => null() type(field_array_type), pointer :: mr_array => null() - type(field_array_type), pointer :: moist_dyn_array => null() type(field_array_type), pointer :: ls_mr_array => null() - type(field_array_type), pointer :: ls_moist_dyn_array => null() - - real(r_def) :: gamma_u, gamma_rho, gamma_exner, gamma_theta - real(r_def) :: gamma_moist_dyn, gamma_mr - real(r_def) :: norm_u, norm_rho, norm_exner, norm_theta - real(r_def) :: norm_moist_dyn, norm_mr - real(r_def) :: norm_diff, norm_diff_prev - real(r_def) :: norm_moist_dyn_tmp, norm_mr_tmp - real(r_def), parameter :: tol = 1.e-2_r_def + real(r_def) :: gamma_u, gamma_rho, gamma_theta + real(r_def) :: gamma_mr + real(r_def) :: norm_u, norm_rho, norm_theta + real(r_def) :: norm_mr + real(r_def) :: norm_mr_tmp + integer(i_def), parameter :: n_variables = 4 + real(r_def) :: array_norm(n_variables), array_norm_prev(n_variables) + character(str_def) :: array_names(n_variables) + real(r_def), parameter :: tol = 5.e-2_r_def + real(r_def), parameter :: indiv_tol = 5.e-1_r_def integer :: n, outer, i call log_event( "TL Test: " // trim(label), & - LOG_LEVEL_INFO ) + LOG_LEVEL_INFO ) prognostic_fields => modeldb%fields%get_field_collection( & "prognostic_fields") ls_fields => modeldb%fields%get_field_collection("ls_fields") moisture_fields => modeldb%fields%get_field_collection("moisture_fields") call moisture_fields%get_field("mr", mr_array) - call moisture_fields%get_field("moist_dyn", moist_dyn_array) mr => mr_array%bundle - moist_dyn => moist_dyn_array%bundle call moisture_fields%get_field("ls_mr", ls_mr_array) - call moisture_fields%get_field("ls_moist_dyn", ls_moist_dyn_array) ls_mr => ls_mr_array%bundle - ls_moist_dyn => ls_moist_dyn_array%bundle ! Input call ls_fields%get_field('ls_u', ls_u) @@ -128,6 +121,12 @@ module tl_test_transport_control_mod call ls_fields%get_field('ls_theta', ls_theta) call ls_fields%get_field('ls_exner', ls_exner) + ! Overwrite the moisture fields with potential temperature + do i = 1, nummr + call invoke( & + setval_X( ls_mr(i), ls_theta)) + end do + call ls_state(igh_u)%initialise( vector_space = ls_u%get_function_space() ) call ls_state(igh_t)%initialise( vector_space = ls_theta%get_function_space() ) call ls_state(igh_d)%initialise( vector_space = ls_rho%get_function_space() ) @@ -144,11 +143,6 @@ module tl_test_transport_control_mod call clone_bundle(ls_state, n2_rhs, bundle_size) call clone_bundle(ls_state, diff, bundle_size) - call clone_bundle(moist_dyn, p_moist_dyn, num_moist_factors) - call clone_bundle(moist_dyn, r_moist_dyn, num_moist_factors) - call clone_bundle(moist_dyn, n_moist_dyn, num_moist_factors) - call clone_bundle(moist_dyn, diff_moist_dyn, num_moist_factors) - call clone_bundle(mr, r_mr, nummr) call clone_bundle(mr, p_mr_in, nummr) call clone_bundle(mr, n_mr_in, nummr) @@ -161,23 +155,36 @@ module tl_test_transport_control_mod setval_X(ls_state(igh_u), ls_u ), & setval_X(ls_state(igh_t), ls_theta), & setval_X(ls_state(igh_d), ls_rho ), & - setval_X(ls_state(igh_p), ls_exner), & + setval_X(ls_state(igh_p), ls_exner ), & setval_X(ls_advected_u, ls_u ) ) call gungho_transport_control_alg_init( mesh ) - call invoke( assign_field_random_kernel_type( random(igh_u), 1.0_r_def ) , & - assign_field_random_kernel_type( random(igh_d), 1.0_r_def ) , & - assign_field_random_kernel_type( random(igh_t), 1.0_r_def ) , & - assign_field_random_kernel_type( random(igh_p), 1.0_r_def ) ) + ! Perturbation + call prognostic_fields%get_field('u', u) + call prognostic_fields%get_field('rho', rho) + call prognostic_fields%get_field('theta', theta) + + ! Set the 'random perturbation as the ls_state plus pert' + call invoke( name = "copy_fields_to_state", & + setval_X(random(igh_u), ls_u ), & + setval_X(random(igh_t), ls_theta), & + setval_X(random(igh_d), ls_rho ) ) + + do i = 1, nummr + call invoke( & + setval_X( r_mr(i), ls_mr(i) )) + end do - do i = 1, num_moist_factors - call invoke( assign_field_random_kernel_type( r_moist_dyn(i), 1.0_r_def ) ) - enddo + call invoke( name = "inc", & + inc_X_plus_Y(random(igh_u), u ), & + inc_X_plus_Y(random(igh_t), theta), & + inc_X_plus_Y(random(igh_d), rho ) ) do i = 1, nummr - call invoke( assign_field_random_kernel_type( r_mr(i), 1.0_r_def ) ) - enddo + call invoke( & + inc_X_plus_Y( r_mr(i), theta )) + end do call set_bundle_scalar( 0.0_r_def, n1_rhs, bundle_size ) @@ -192,19 +199,15 @@ module tl_test_transport_control_mod outer, & cheap_update = .false.) - gamma_u = 7.e8_r_def - gamma_theta = 1.e5_r_def - gamma_rho = 1.e5_r_def - gamma_exner = 1.e5_r_def - gamma_moist_dyn=1.e0_r_def - gamma_mr = 1.e0_r_def + gamma_u = 1._r_def + gamma_theta = 1._r_def + gamma_rho = 1._r_def + gamma_mr = 1._r_def do n=1,2 gamma_u = gamma_u/2.0_r_def gamma_theta = gamma_theta/2.0_r_def gamma_rho = gamma_rho/2.0_r_def - gamma_exner = gamma_exner/2.0_r_def - gamma_moist_dyn = gamma_moist_dyn/2.0_r_def gamma_mr = gamma_mr/2.0_r_def call set_bundle_scalar( 0.0_r_def, n2_rhs, bundle_size ) @@ -212,7 +215,7 @@ module tl_test_transport_control_mod call invoke( a_times_X( p_state(igh_u), gamma_u, random(igh_u) ), & a_times_X( p_state(igh_t), gamma_theta, random(igh_t) ), & a_times_X( p_state(igh_d), gamma_rho, random(igh_d) ), & - a_times_X( p_state(igh_p), gamma_exner, random(igh_p) ), & + setval_c( p_state(igh_p), 0.0_r_def ), & a_times_X( p_advected_u, gamma_u, random(igh_u) ) ) ! state = ls_state + p_state @@ -221,13 +224,6 @@ module tl_test_transport_control_mod call invoke( setval_X( n_advected_u, ls_advected_u), & inc_X_plus_Y(n_advected_u, p_advected_u ) ) - do i = 1, num_moist_factors - call invoke( & - a_times_X( p_moist_dyn(i), gamma_moist_dyn, r_moist_dyn(i) ), & - setval_X( n_moist_dyn(i), ls_moist_dyn(i) ), & - inc_X_plus_Y( n_moist_dyn(i), p_moist_dyn(i) ) ) - end do - do i = 1, nummr call invoke( & a_times_X( p_mr_in(i), gamma_mr, r_mr(i) ), & @@ -263,63 +259,43 @@ module tl_test_transport_control_mod call invoke( & inc_X_minus_Y( diff(igh_u), p_rhs(igh_u) ), & inc_X_minus_Y( diff(igh_t), p_rhs(igh_t) ), & - inc_X_minus_Y( diff(igh_d), p_rhs(igh_d) ), & - inc_X_minus_Y( diff(igh_p), p_rhs(igh_p) ) ) + inc_X_minus_Y( diff(igh_d), p_rhs(igh_d) ) ) - call invoke( X_innerproduct_X( norm_u, diff(igh_u) ) , & + call invoke( & + X_innerproduct_X( norm_u, diff(igh_u) ) , & X_innerproduct_X( norm_rho, diff(igh_d) ) , & - X_innerproduct_X( norm_theta, diff(igh_t) ) , & - X_innerproduct_X( norm_exner, diff(igh_p) ) ) + X_innerproduct_X( norm_theta, diff(igh_t) ) ) - norm_moist_dyn=0.0_r_def - do i = 1, num_moist_factors + + do i = 1, nummr call invoke( & - X_minus_Y( diff_moist_dyn(i), n_moist_dyn(i), moist_dyn(i) ), & - inc_X_minus_Y( diff_moist_dyn(i), p_moist_dyn(i) ), & - X_innerproduct_X( norm_moist_dyn_tmp, diff_moist_dyn(i) ) ) - norm_moist_dyn = norm_moist_dyn + norm_moist_dyn_tmp + X_minus_Y( diff_mr(i), n_mr_out(i), ls_mr_out(i) ), & + inc_X_minus_Y( diff_mr(i), p_mr_out(i) ) ) end do norm_mr=0.0_r_def do i = 1, nummr - call invoke( & - X_minus_Y( diff_mr(i), n_mr_out(i), ls_mr_out(i) ), & - inc_X_minus_Y( diff_mr(i), p_mr_out(i) ), & + call invoke( & X_innerproduct_X( norm_mr_tmp, diff_mr(i) ) ) norm_mr = norm_mr + norm_mr_tmp end do - write( log_scratch_space, & - '(A, E32.12, A, E32.12 )' ) & - ' norm_u = ' , norm_u, & - ' norm_rho = ' , norm_rho - - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - write( log_scratch_space, & - '(A, E32.12, A, E32.12 )' ) & - ' norm_theta = ' , norm_theta, & - ' norm_moist_dyn = ' , norm_moist_dyn - - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - write( log_scratch_space, & - '(A, E32.12, A, E32.12 )' ) & - ' norm_exner = ' , norm_exner, & - ' norm_mr = ' , norm_mr - - call log_event( log_scratch_space, LOG_LEVEL_INFO ) - - norm_diff = norm_rho + norm_theta + norm_exner + norm_u & - + norm_moist_dyn + norm_mr - norm_diff = sqrt(norm_diff) + array_norm(1) = norm_u + array_norm(2) = norm_rho + array_norm(3) = norm_theta + array_norm(4) = norm_mr + array_names(1) = 'norm_u' + array_names(2) = 'norm_rho' + array_names(3) = 'norm_theta' + array_names(4) = 'norm_mr' if (n == 2) then - call convergence_rate_check( norm_diff, norm_diff_prev, & - label, tol=tol ) + call array_convergence_rate_check( array_norm, array_norm_prev, & + array_names, n_variables, label, tol=tol, indiv_tol=indiv_tol) end if - norm_diff_prev = norm_diff + array_norm_prev = array_norm + end do end subroutine test_transport_control diff --git a/science/linear/integration-test/tl_test/tl_test_vorticity_mod.x90 b/science/linear/integration-test/tl_test/tl_test_vorticity_mod.x90 index 47e5cdfc0..c129dd3f2 100644 --- a/science/linear/integration-test/tl_test/tl_test_vorticity_mod.x90 +++ b/science/linear/integration-test/tl_test/tl_test_vorticity_mod.x90 @@ -203,8 +203,6 @@ module tl_test_vorticity_mod inc_X_minus_Y( diff, p_rhs_u ), & X_innerproduct_X( norm_diff, diff ) ) - norm_diff = sqrt(norm_diff) - write( log_scratch_space, '(A, E32.12, A, E32.12)' ) & 'gamma = ', gamma, ' norm = ', norm_diff diff --git a/applications/linear_model/plot_convergence/plot_convergence.py b/science/linear/plot_convergence/plot_convergence.py similarity index 54% rename from applications/linear_model/plot_convergence/plot_convergence.py rename to science/linear/plot_convergence/plot_convergence.py index 811421c89..6d7c42ea7 100644 --- a/applications/linear_model/plot_convergence/plot_convergence.py +++ b/science/linear/plot_convergence/plot_convergence.py @@ -14,6 +14,7 @@ import os import pandas as pd import matplotlib.pyplot as plt +import numpy as np def plot_data(filename, axes, variable, color, shape): @@ -37,12 +38,55 @@ def plot_data(filename, axes, variable, color, shape): norm_df = pd.DataFrame(norm_line, columns=['gamma', 'norm']) datafile.close() + + # Square root (as the read data is only the inner product and + # has not included the square root to give the norm) + norm_df['norm'] = np.sqrt(norm_df['norm']) + + # Normalise - to give a relative error + normalise = norm_df['norm'].iloc[4] + norm_df['norm'] = norm_df['norm'] / normalise + + # Plot the data + if (CONFIG == 'nwp_gal9'): + ymin = 10**-2 + ymax = 10**2 + xmin = 10**-3 + xmax = 10**1 + elif (CONFIG == 'semi_implicit'): + ymin = 10**-2 + ymax = 10**2 + xmin = 10**-1 + xmax = 10**4 + elif (CONFIG == 'runge_kutta'): + ymin = 10**-3 + ymax = 10**2 + xmin = 10**-1 + xmax = 10**4 + else: + print(CONFIG+' not listed') + + norm_df.plot.scatter(x='gamma', y='norm', loglog=True, + xlim=(xmin, xmax), + ylim=(ymin, ymax), + ax=axes, color=color, + marker=shape, label = variable) + + # Check extremes + norm_min = norm_df['norm'].min() + norm_max = norm_df['norm'].max() + if (norm_min < ymin) : + print('Warning: Min value is'+ str(norm_min)) + if (norm_max > ymax) : + print('Warning: Max value is'+ str(norm_max)) + + # Plot the expected line + centre = norm_df['gamma'].iloc[4] + expected_x = [10**-2 *centre, centre, 100* centre] + expected_y = [10**-2, 10**0, 100] + plt.plot(expected_x, expected_y) - norm_df.plot.scatter(x='gamma', y='norm', loglog=True, xlim=(10**0, 10**5), - ylim=(10**-5, 10**0), ax=axes, color=color, - marker=shape) - - + def make_plot(directory, filename): ''' Plot the data for the different prognostic variables, together with the @@ -55,27 +99,25 @@ def make_plot(directory, filename): plot_data(directory + filename, axs, 'gamma_u', 'r', 'o') plot_data(directory + filename, axs, 'gamma_exner', 'b', 's') plot_data(directory + filename, axs, 'gamma_theta', 'g', '^') - plot_data(directory + filename, axs, 'gamma_total', 'black', 'x') - plot_data(directory + filename, axs, 'gamma_mr', 'm', '*') + plot_data(directory + filename, axs, 'gamma_mr', 'black', 'x') - expected_x = [10**0, 10**5] - expected_y = [10**-5, 10**0] - plt.plot(expected_x, expected_y) - - plt.legend(['Expected gradient (linear)', 'density', 'momentum', - 'exner pressure', 'potential temperature', 'total', - 'moisture mixing ratios'], - loc='lower right') + plt.legend(loc='lower right') plt.xlabel('Gamma') plt.ylabel('Relative error') plt.title('Validity of the tangent linear model') - plt.show() + # To show the plot to the screen, uncommment plt.show() + #plt.show() + + # Save the plot to a file + plt.savefig(directory + filename + "convergence_plot.png") if __name__ == "__main__": DATA_DIRECTORY = os.getcwd()+'/' DATA_FILENAME = 'outfile' + CONFIG = os.getenv('CONFIG') + print(CONFIG) make_plot(DATA_DIRECTORY, DATA_FILENAME) diff --git a/science/linear/plot_convergence/plot_convergence.sh b/science/linear/plot_convergence/plot_convergence.sh new file mode 100755 index 000000000..8b60e5331 --- /dev/null +++ b/science/linear/plot_convergence/plot_convergence.sh @@ -0,0 +1,118 @@ +############################################################################## +# (c) Crown copyright 2022 Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + +#---------------------------------------------------------------------- +# Plots the convergence rate of the tangent linear model. +#---------------------------------------------------------------------- + +# INSTRUCTIONS TO RUN +# 1. Specify the config_list +# 2. Run using . plot_convergence.sh, from the plot_convergence directory + +# SCIENCE DETAILS +# The relative linearisation error is +# E = || N(x+ gamma x') - N(x) - L(x) gamma x' || / || L(x) gamma x' || +# where N=nonlinear model, L=linear model, x=linearisation state +# x'=perturbation, gamma=scalar. +# From the Taylor series expansion, E(gamma) = O(gamma) i.e. of the order gamma +# So the relative error should be a linear function of gamma + +# SCRIPT STEPS +# 1. Build the model +# 2. Produce the data: The integration test tl_test_timesteps is extended by +# running over 10 values of gamma, rather than 2 values of gamma. +# 3. Plot the data: The data is plotted for each prognostic variable. + +# EXTENSION +# The plot_configuration.nml can also be extended to other configurations e.g +# * increase the number of timesteps (timesteps_end) +# * increase the number of timesteps between updating the linearisation state +# (update_ls_frequency) + +#-------------------------------------------------------------------------- + +######################## Functions ########################################## +build(){ + echo $CONFIG " Building the executable" + + # Integration tests executable name + exe=$Linear_dir/test/$CONFIG/$CONFIG + + # Build the integration tests, unless that has already been completed + if [ -f $exe ] ; then + echo "Do not need to build the executable as $exe exists" + else + echo "$exe does not exist, so now building the executable" + cd $Root_dir/build + python3 local_build.py linear -t integration-tests + + if [$? -ne 0 ]; then + echo "Error building the executable" + return + fi + fi +} + +integration_test(){ + # Setup the configuration - to test with 10 values of gamma + echo $CONFIG " Setting up the configuration" + cd $Linear_dir/integration-test/$CONFIG/resources/ + cp ${CONFIG}_configuration.nml plot_configuration.nml + sed -i 's/number_gamma_values=2/number_gamma_values=10/g' plot_configuration.nml + if [ $? -ne 0 ]; then + echo "Error in creating plot_configuration.nml" + return + else + echo "plot_configuration.nml created in " $PWD + fi + + # Run the tl_test_timesteps integration test + echo $CONFIG " Running the integration test" + cd $Linear_dir/integration-test/$CONFIG + echo $PWD + $exe resources/plot_configuration.nml test_timesteps > outfile + if [ $? -ne 0 ]; then + echo "Error in creating outfile data" + return + else + echo "Data created successfully" + fi +} + +plot(){ + # Plot the data, together with the expected gradient + echo $CONFIG " Plotting the data" + cd $Linear_dir/integration-test/$CONFIG + python $Linear_dir/plot_convergence/plot_convergence.py +} + +#################### MAIN PROGRAM ################################################# + +# Modules +module purge +module use /home/users/lfricadmin/lmod +module load lfric/vn3.0 +module load scitools + +config_list=(nwp_gal9 semi_implicit runge_kutta) + +# Directory of this script +SCRIPT_DIR="$(dirname "$(realpath "$BASH_SOURCE")")" +# And parent directories +export Linear_dir="$(dirname $SCRIPT_DIR)" +export Parent_dir="$(dirname $Linear_dir)" +export Root_dir="$(dirname $Parent_dir)" +echo "Linear_dir" $Linear_dir +echo "Root_dir" $Root_dir + +for configuration in "${config_list[@]}"; do + echo $configuration + export CONFIG="$configuration" + + build + integration_test + plot +done diff --git a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf index 98a373e47..4091f0aa2 100644 --- a/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf +++ b/science/linear/rose-meta/lfric-linear/HEAD/rose-meta.conf @@ -4,7 +4,7 @@ import=lfric-gungho/HEAD compulsory=true description=Provides extra information for the tangent linear model. help= -ns=namelist/Linear/Initial +ns=namelist/Linear sort-key=Section-A07 title=Linear @@ -13,6 +13,7 @@ compulsory=true description=Do not update the linearisation state during the timestep. help=The linearisation state is the same for every outer and inner loop. !kind=default +ns=namelist/Linear/Efficiency type=logical [namelist:linear=l_stabilise_bl] @@ -20,7 +21,7 @@ compulsory=true description=?????? help=If true then turn on boundary layer stabilisation in linear model !kind=default -ns=namelist/Job/Timestepping/semi-implicit +ns=namelist/Linear/BoundaryLayer type=logical [namelist:linear=ls_read_w2h] @@ -30,7 +31,7 @@ description=For the linearisation state, read winds on a W2h space =from a file. help=Horizontal winds are read in on a W2h space from the ls file. If =false, then cell-centres (W3), co-located winds are assumed. -sort-key=Panel-A07a +ns=namelist/Linear/Data type=logical [namelist:linear=max_bl_stabilisation] @@ -39,7 +40,7 @@ description=?????? fail-if=this < 0.0 help=Maximum boundary layer stabilisation scalar in linear model !kind=default -ns=namelist/Job/Timestepping/semi-implicit +ns=namelist/Linear/BoundaryLayer range=0.0: type=real @@ -49,7 +50,7 @@ description=?????? fail-if=this < 1 ; help=Number of boundary layers levels to stabilise in linear model !kind=default -ns=namelist/Job/Timestepping/semi-implicit +ns=namelist/Linear/BoundaryLayer range=1: type=integer @@ -61,20 +62,130 @@ help=This can be an analytical perturbation, random data or from a file. =The analytical perturbation is based on the DCMIP gravity wave test. =The random data is generated with the Fortran intrinsic function 'random_number'. =The file contains data produced from LFRic with horizontal winds in W2. -ns=namelist/Linear/Initial -sort-key=Panel-A07a +ns=namelist/Linear/Data value-titles=analytic, =random, =file, =zero values='analytic', 'random', 'file', 'zero' +[namelist:linear=transport_efficiency] +compulsory=true +description=Do not update the linearisation state during the transport step. +help=The linearisation state remains fixed. +!kind=default +ns=namelist/Linear/Efficiency +type=logical + +[namelist:linear_physics] +compulsory=true +description=Settings for TLM physics schemes. +ns=namelist/Linear/Physics +sort-key=Section-A07 +title=Linear Physics + +[namelist:linear_physics=blevs_m] +compulsory=true +description=Number of momentum boundary layer levels in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Determines levels from surface upwards over which tl_bdy_lyr_alg is applied. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=e_folding_levs_m] +compulsory=true +description=e-folding level in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Number of e-folding levels in exchange coefficient for momentum. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=l_0_m] +compulsory=true +description=Height parameter for TLM boundary layer scheme. +fail-if=this < 0.0 +help=Mixing length for momentum. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=l_boundary_layer] +compulsory=true +description=Logical switch for TLM boundary layer scheme. +help=If true then turn on boundary layer in linear model and adjoint. +!kind=default +ns=namelist/Linear/Physics +sort-key=Panel-A00 +trigger=namelist:linear_physics=blevs_m: .true. ; + =namelist:linear_physics=l_0_m: .true. ; + =namelist:linear_physics=e_folding_levs_m: .true. ; + =namelist:linear_physics=log_layer: .true. ; + =namelist:linear_physics=u_land_m: .true. ; + =namelist:linear_physics=u_sea_m: .true. ; + =namelist:linear_physics=z_land_m: .true. ; + =namelist:linear_physics=z_sea_m: .true. ; +type=logical + +[namelist:linear_physics=log_layer] +compulsory=true +description=Number of levels in log layer in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Number of levels in log layer in TLM boundary layer scheme. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=u_land_m] +compulsory=true +description=Land friction velocity in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Friction velocity for momentum over land. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=u_sea_m] +compulsory=true +description=Sea friction velocity in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Friction velocity for momentum over sea. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=z_land_m] +compulsory=true +description=Friction height over land in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Effective roughness length for momentum over land. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=z_sea_m] +compulsory=true +description=Friction height over sea in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Effective roughness length for momentum over sea. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + [namelist:validity_test] compulsory=true description=Provides settings for the tangent linear validity tests. help=The validity tests are performed using the integration test framework. ns=namelist/Linear/ValidityTest -sort-key=Section-A07 title=Validity Tests [namelist:validity_test=number_gamma_values] @@ -87,7 +198,6 @@ help=Gamma is the size of the perturbation used in the validity test. !kind=default ns=namelist/Linear/ValidityTest range=0: -sort-key=Panel-A07b type=integer [namelist:validity_test=update_ls_frequency] @@ -102,5 +212,4 @@ help=In the integration tests, when running over multiple timesteps, !kind=default ns=namelist/Linear/ValidityTest range=0: -sort-key=Panel-A07c type=integer diff --git a/science/linear/rose-meta/lfric-linear/version30_31.py b/science/linear/rose-meta/lfric-linear/version30_31.py new file mode 100644 index 000000000..43e7c5792 --- /dev/null +++ b/science/linear/rose-meta/lfric-linear/version30_31.py @@ -0,0 +1,279 @@ +import re +import sys + +from metomi.rose.upgrade import MacroUpgrade + +from .version22_30 import * + + +class UpgradeError(Exception): + """Exception created when an upgrade fails.""" + + def __init__(self, msg): + self.msg = msg + + def __repr__(self): + sys.tracebacklimit = 0 + return self.msg + + __str__ = __repr__ + + +""" +Copy this template and complete to add your macro +class vnXX_txxx(MacroUpgrade): + # Upgrade macro for by + BEFORE_TAG = "vnX.X" + AFTER_TAG = "vnX.X_txxx" + def upgrade(self, config, meta_config=None): + # Add settings + return config, self.reports +""" + + +class vn30_t99(MacroUpgrade): + """Upgrade macro for ticket #99 by Fred Wobus.""" + + BEFORE_TAG = "vn3.0" + AFTER_TAG = "vn3.0_t99" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-lfric_atm + """Set segmentation size for Gregory-Rowntree convection kernel""" + self.add_setting(config, ["namelist:physics", "conv_gr_segment"], "16") + return config, self.reports + + +class vn30_t146(MacroUpgrade): + """Upgrade macro for ticket #146 by Maggie Hendry.""" + + BEFORE_TAG = "vn3.0_t99" + AFTER_TAG = "vn3.0_t146" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/jules-lfric + # Add jules_model_environment_lfric namelist + source = self.get_setting_value( + config, ["file:configuration.nml", "source"] + ) + source = re.sub( + r"namelist:jules_hydrology", + r"namelist:jules_hydrology)" + + "\n" + + " (namelist:jules_model_environment_lfric", + source, + ) + self.change_setting_value( + config, ["file:configuration.nml", "source"], source + ) + self.add_setting( + config, + ["namelist:jules_model_environment_lfric", "l_jules_parent"], + "'lfric'", + ) + # Add jules_surface namelist items + self.add_setting( + config, + ["namelist:jules_surface", "all_tiles"], + "'off'", + ) + self.add_setting(config, ["namelist:jules_surface", "beta1"], "0.83") + self.add_setting(config, ["namelist:jules_surface", "beta2"], "0.93") + self.add_setting( + config, ["namelist:jules_surface", "beta_cnv_bl"], "0.04" + ) + self.add_setting( + config, + ["namelist:jules_surface", "fd_hill_option"], + "'capped_lowhill'", + ) + self.add_setting(config, ["namelist:jules_surface", "fwe_c3"], "0.5") + self.add_setting( + config, ["namelist:jules_surface", "fwe_c4"], "20000.0" + ) + self.add_setting(config, ["namelist:jules_surface", "hleaf"], "5.7e4") + self.add_setting(config, ["namelist:jules_surface", "hwood"], "1.1e4") + self.add_setting( + config, ["namelist:jules_surface", "i_modiscopt"], "'on'" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_epot_corr"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_land_ice_imp"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_mo_buoyancy_calc"], ".true." + ) + self.add_setting( + config, ["namelist:jules_surface", "orog_drag_param"], "0.15" + ) + self.add_setting( + config, ["namelist:jules_surface", "l_flake_model"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_land_ice"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_elev_lw_down"], ".false." + ) + self.add_setting( + config, ["namelist:jules_surface", "l_point_data"], ".false." + ) + return config, self.reports + + +class vn30_t135(MacroUpgrade): + """Upgrade macro for ticket #135 by James Manners.""" + + BEFORE_TAG = "vn3.0_t146" + AFTER_TAG = "vn3.0_t135" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/socrates-radiation + self.add_setting(config, ["namelist:cosp", "n_cosp_step"], "1") + return config, self.reports + + +class vn30_t171(MacroUpgrade): + """Upgrade macro for ticket #171 by James Kent.""" + + BEFORE_TAG = "vn3.0_t135" + AFTER_TAG = "vn3.0_t171" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + # Add adjust_tracer_equation to transport namelist + self.add_setting( + config, ["namelist:transport", "adjust_tracer_equation"], ".false." + ) + return config, self.reports + + +class vn30_t214(MacroUpgrade): + """Upgrade macro for ticket #214 by mark Hedley.""" + + BEFORE_TAG = "vn3.0_t171" + AFTER_TAG = "vn3.0_t214" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-gungho + """Set segments configuration to true.""" + self.change_setting_value( + config, ["namelist:physics", "configure_segments"], ".true." + ) + + +class vn30_t108(MacroUpgrade): + """Upgrade macro for ticket #108 by Christine Johnson.""" + + BEFORE_TAG = "vn3.0_t214" + AFTER_TAG = "vn3.0_t108" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + fixed_ls = self.get_setting_value( + config, ["namelist:linear", "fixed_ls"] + ) + if ".true." in fixed_ls: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".true." + ) + else: + self.add_setting( + config, ["namelist:linear", "transport_efficiency"], ".false." + ) + return config, self.reports + + +class vn30_t182(MacroUpgrade): + """Upgrade macro for ticket #182 by Tom Hill.""" + + BEFORE_TAG = "vn3.0_t108" + AFTER_TAG = "vn3.0_t182" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/lfric-linear + """Add linear boundary layer physics scheme""" + scaling = self.get_setting_value( + config, ["namelist:planet", "scaling_factor"] + ) + if "125.0" in scaling: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".false.", + ) + else: + self.add_setting( + config, + ["namelist:linear_physics", "l_boundary_layer"], + ".true.", + ) + self.add_setting( + config, ["namelist:linear_physics", "Blevs_m"], "15" + ) + self.add_setting( + config, ["namelist:linear_physics", "e_folding_levs_m"], "10" + ) + self.add_setting( + config, ["namelist:linear_physics", "l_0_m"], "80.0" + ) + self.add_setting( + config, ["namelist:linear_physics", "log_layer"], "2" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_land_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "u_sea_m"], "0.4" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_land_m"], "0.05" + ) + self.add_setting( + config, ["namelist:linear_physics", "z_sea_m"], "0.0005" + ) + return config, self.reports + + +class vn30_t306(MacroUpgrade): + """Upgrade macro for ticket TTTT by Unknown.""" + + BEFORE_TAG = "vn3.0_t182" + AFTER_TAG = "vn3.1" + + def upgrade(self, config, meta_config=None): + # Commands From: rose-meta/um-stochastic_physics + # Blank Upgrade Macro + # Commands From: rose-meta/um-spectral_gwd + # Blank Upgrade Macro + # Commands From: rose-meta/um-orographic_drag + # Blank Upgrade Macro + # Commands From: rose-meta/um-microphysics + # Blank Upgrade Macro + # Commands From: rose-meta/um-iau + # Blank Upgrade Macro + # Commands From: rose-meta/um-convection + # Blank Upgrade Macro + # Commands From: rose-meta/um-cloud + # Blank Upgrade Macro + # Commands From: rose-meta/um-chemistry + # Blank Upgrade Macro + # Commands From: rose-meta/um-boundary_layer + # Blank Upgrade Macro + # Commands From: rose-meta/um-aerosol + # Blank Upgrade Macro + # Commands From: rose-meta/socrates-radiation + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lfric + # Blank Upgrade Macro + # Commands From: rose-meta/jules-lsm + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-driver + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-gungho + # Blank Upgrade Macro + # Commands From: rose-meta/lfric-linear + # Blank Upgrade Macro + return config, self.reports diff --git a/science/linear/rose-meta/lfric-linear/versions.py b/science/linear/rose-meta/lfric-linear/versions.py index 152c043d0..01798ad2b 100644 --- a/science/linear/rose-meta/lfric-linear/versions.py +++ b/science/linear/rose-meta/lfric-linear/versions.py @@ -1,8 +1,8 @@ import sys -from metomi.rose.upgrade import MacroUpgrade +from metomi.rose.upgrade import MacroUpgrade # noqa: F401 -from .version22_30 import * +from .version30_31 import * class UpgradeError(Exception): diff --git a/science/linear/rose-meta/lfric-linear/vn3.1/rose-meta.conf b/science/linear/rose-meta/lfric-linear/vn3.1/rose-meta.conf new file mode 100644 index 000000000..0301563b4 --- /dev/null +++ b/science/linear/rose-meta/lfric-linear/vn3.1/rose-meta.conf @@ -0,0 +1,215 @@ +import=lfric-gungho/vn3.1 + +[namelist:linear] +compulsory=true +description=Provides extra information for the tangent linear model. +help= +ns=namelist/Linear +sort-key=Section-A07 +title=Linear + +[namelist:linear=fixed_ls] +compulsory=true +description=Do not update the linearisation state during the timestep. +help=The linearisation state is the same for every outer and inner loop. +!kind=default +ns=namelist/Linear/Efficiency +type=logical + +[namelist:linear=l_stabilise_bl] +compulsory=true +description=?????? +help=If true then turn on boundary layer stabilisation in linear model +!kind=default +ns=namelist/Linear/BoundaryLayer +type=logical + +[namelist:linear=ls_read_w2h] +compulsory=true +!default=kind +description=For the linearisation state, read winds on a W2h space + =from a file. +help=Horizontal winds are read in on a W2h space from the ls file. If + =false, then cell-centres (W3), co-located winds are assumed. +ns=namelist/Linear/Data +type=logical + +[namelist:linear=max_bl_stabilisation] +compulsory=false +description=?????? +fail-if=this < 0.0 +help=Maximum boundary layer stabilisation scalar in linear model +!kind=default +ns=namelist/Linear/BoundaryLayer +range=0.0: +type=real + +[namelist:linear=n_bl_levels_to_stabilise] +compulsory=false +description=?????? +fail-if=this < 1 ; +help=Number of boundary layers levels to stabilise in linear model +!kind=default +ns=namelist/Linear/BoundaryLayer +range=1: +type=integer + +[namelist:linear=pert_option] +compulsory=true +description=Method to generate the perturbation. +!enumeration=true +help=This can be an analytical perturbation, random data or from a file. + =The analytical perturbation is based on the DCMIP gravity wave test. + =The random data is generated with the Fortran intrinsic function 'random_number'. + =The file contains data produced from LFRic with horizontal winds in W2. +ns=namelist/Linear/Data +value-titles=analytic, + =random, + =file, + =zero +values='analytic', 'random', 'file', 'zero' + +[namelist:linear=transport_efficiency] +compulsory=true +description=Do not update the linearisation state during the transport step. +help=The linearisation state remains fixed. +!kind=default +ns=namelist/Linear/Efficiency +type=logical + +[namelist:linear_physics] +compulsory=true +description=Settings for TLM physics schemes. +ns=namelist/Linear/Physics +sort-key=Section-A07 +title=Linear Physics + +[namelist:linear_physics=blevs_m] +compulsory=true +description=Number of momentum boundary layer levels in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Determines levels from surface upwards over which tl_bdy_lyr_alg is applied. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=e_folding_levs_m] +compulsory=true +description=e-folding level in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Number of e-folding levels in exchange coefficient for momentum. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=l_0_m] +compulsory=true +description=Height parameter for TLM boundary layer scheme. +fail-if=this < 0.0 +help=Mixing length for momentum. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=l_boundary_layer] +compulsory=true +description=Logical switch for TLM boundary layer scheme. +help=If true then turn on boundary layer in linear model and adjoint. +!kind=default +ns=namelist/Linear/Physics +sort-key=Panel-A00 +trigger=namelist:linear_physics=blevs_m: .true. ; + =namelist:linear_physics=l_0_m: .true. ; + =namelist:linear_physics=e_folding_levs_m: .true. ; + =namelist:linear_physics=log_layer: .true. ; + =namelist:linear_physics=u_land_m: .true. ; + =namelist:linear_physics=u_sea_m: .true. ; + =namelist:linear_physics=z_land_m: .true. ; + =namelist:linear_physics=z_sea_m: .true. ; +type=logical + +[namelist:linear_physics=log_layer] +compulsory=true +description=Number of levels in log layer in TLM boundary layer scheme. +fail-if=this < 1 ; +help=Number of levels in log layer in TLM boundary layer scheme. +!kind=default +ns=namelist/Linear/Physics +range=1: +type=integer + +[namelist:linear_physics=u_land_m] +compulsory=true +description=Land friction velocity in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Friction velocity for momentum over land. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=u_sea_m] +compulsory=true +description=Sea friction velocity in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Friction velocity for momentum over sea. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=z_land_m] +compulsory=true +description=Friction height over land in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Effective roughness length for momentum over land. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:linear_physics=z_sea_m] +compulsory=true +description=Friction height over sea in TLM boundary layer scheme. +fail-if=this < 0.0 +help=Effective roughness length for momentum over sea. +!kind=default +ns=namelist/Linear/Physics +range=0.0: +type=real + +[namelist:validity_test] +compulsory=true +description=Provides settings for the tangent linear validity tests. +help=The validity tests are performed using the integration test framework. +ns=namelist/Linear/ValidityTest +title=Validity Tests + +[namelist:validity_test=number_gamma_values] +compulsory=true +description=The number of values of gamma to loop through. +fail-if=this <0 ; +help=Gamma is the size of the perturbation used in the validity test. + =For standard testing (i.e. through rose), the number of gamma values should be 2. + =But to create a graph of the relative error against gamma, then a value around 10 should be used. +!kind=default +ns=namelist/Linear/ValidityTest +range=0: +type=integer + +[namelist:validity_test=update_ls_frequency] +compulsory=true +description=The frequency to update the linearisation state. +fail-if=this <0 ; +help=In the integration tests, when running over multiple timesteps, + = the linearisation state is produced by stepping the nonlinear model + = and then copying this output to the linearisation state. + = The update_frequency controls how often to copy the output to the + = linearisation state, e.g. every 3 timesteps. +!kind=default +ns=namelist/Linear/ValidityTest +range=0: +type=integer diff --git a/science/linear/source/algorithm/core_dynamics/tl_rhs_alg_mod.x90 b/science/linear/source/algorithm/core_dynamics/tl_rhs_alg_mod.x90 index 2d329e9d8..ba8c02b25 100644 --- a/science/linear/source/algorithm/core_dynamics/tl_rhs_alg_mod.x90 +++ b/science/linear/source/algorithm/core_dynamics/tl_rhs_alg_mod.x90 @@ -39,8 +39,8 @@ module tl_rhs_alg_mod use quadrature_rule_gaussian_mod, only: quadrature_rule_gaussian_type use derived_config_mod, only: bundle_size use field_indices_mod, only: igh_u, igh_t, igh_d, igh_p - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use tl_rhs_project_eos_kernel_mod, only: tl_rhs_project_eos_kernel_type use tl_rhs_sample_eos_kernel_mod, only: tl_rhs_sample_eos_kernel_type use moist_dyn_mod, only: num_moist_factors, gas_law @@ -133,8 +133,9 @@ subroutine tl_rhs_alg(rhs, alpha_dt, base_state, state, moist_dyn, & ls_exner_big_halo integer(kind=i_def), parameter :: exner_stencil_depth = 1 + integer(tik) :: id - if ( subroutine_timers ) call timer('rhs_alg') + if ( LPROF ) call start_timing( id, 'tl_dynamics.rhs_alg' ) mesh => base_state(igh_u)%get_mesh() @@ -290,7 +291,7 @@ subroutine tl_rhs_alg(rhs, alpha_dt, base_state, state, moist_dyn, & mesh, reference_element ) - if ( subroutine_timers ) call timer('rhs_alg') + if ( LPROF ) call stop_timing( id, 'tl_dynamics.rhs_alg' ) end subroutine tl_rhs_alg diff --git a/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 new file mode 100644 index 000000000..f11d3a2b7 --- /dev/null +++ b/science/linear/source/algorithm/linear_physics/tl_bdy_lyr_alg.x90 @@ -0,0 +1,144 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Given TL state(igh_u) compute TLM boundary layer increment u_bl_inc +module tl_bdy_lyr_alg_mod + + use constants_mod, only: r_def + use field_collection_mod, only: field_collection_type + use integer_field_mod, only: integer_field_type + use driver_modeldb_mod, only: modeldb_type + use sci_geometric_constants_mod, only: get_height_fe, & + get_face_selector_ew, & + get_face_selector_ns + use sci_fem_constants_mod, only: get_rmultiplicity_fe + use field_mod, only: field_type + use linear_physics_config_mod, only: log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_d + use timing_mod, only: start_timing, stop_timing, tik, LPROF + use mesh_mod, only: mesh_type + use fs_continuity_mod, only: W2, W3, Wtheta + use tl_compute_qe_kernel_mod, only: tl_compute_qe_kernel_type + use tl_compute_aubu_kernel_mod, only: tl_compute_aubu_kernel_type + use tl_bl_inc_kernel_mod, only: tl_bl_inc_kernel_type + + implicit none + + private + public :: tl_bdy_lyr_alg + +contains + +!> @brief Given TL state(igh_u) compute TLM boundary layer increment u_bl_inc +!> @details The stages are: +!> 1. Call tl_compute_qe_kernel_type: from LS, compute coefficients Q, E +!> 2. Call tl_compute_aubu_kernel_type: from Q,E, compute coefficients Auv, Buv_inv +!> 3. Call tl_bl_inc_kernel_type: from state(igh_u) use coefficients Auv, Buv_inv to compute u_bl_inc +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!> The original code is at https://wwwspice/~frva/VAR/view/var-2022.12.2/doc/PF_bdy_lyr.html +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u_bl_inc TLM boundary layer increment +!> @param[in,out] u The current TL model prognostic u field, state(igh_u) +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] dt The TL model timestep length +subroutine tl_bdy_lyr_alg(modeldb, u_bl_inc, u, ls_state, dt) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u_bl_inc + type(field_type), intent(inout) :: u + type(field_type), target, intent(in) :: ls_state(bundle_size) + real(kind=r_def), intent(in) :: dt + + type(mesh_type), pointer :: mesh + type(field_type), pointer :: height_w2 + type(field_type), pointer :: height_w3 + type(field_type), pointer :: height_wth + type(field_type), pointer :: w2_rmultiplicity + type(integer_field_type), pointer :: face_selector_ew + type(integer_field_type), pointer :: face_selector_ns + + type(field_collection_type), pointer :: ls_fields + type(field_type), pointer :: ls_land_fraction + + ! Coefficients computed from linearisation state + type(field_type) :: Q + type(field_type) :: E + type(field_type) :: auv + type(field_type) :: buv_inv + + integer(kind=tik) :: id + + if (LPROF) call start_timing(id, 'tl_bdy_lyr_alg') + + ls_fields => modeldb%fields%get_field_collection('ls_fields') + call ls_fields%get_field('ls_land_fraction', ls_land_fraction) + + mesh => u%get_mesh() + height_w2 => get_height_fe(W2, mesh%get_id()) + height_w3 => get_height_fe(W3, mesh%get_id()) + height_wth => get_height_fe(Wtheta, mesh%get_id()) + + w2_rmultiplicity => get_rmultiplicity_fe(W2, mesh%get_id()) + + face_selector_ew => get_face_selector_ew(mesh%get_id()) + face_selector_ns => get_face_selector_ns(mesh%get_id()) + + call u%copy_field_properties(u_bl_inc) + call invoke(setval_c(u_bl_inc, 0.0_r_def)) + + call ls_state(igh_d)%copy_field_properties(Q) + call ls_state(igh_d)%copy_field_properties(E) + + call u%copy_field_properties(auv) + call u%copy_field_properties(buv_inv) + + call invoke(tl_compute_qe_kernel_type(Q, & + E, & + ls_state(igh_d), & + height_w3, & + height_wth, & + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m)) + + call invoke(tl_compute_aubu_kernel_type(auv, & + buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m)) + + call invoke(tl_bl_inc_kernel_type(u_bl_inc, & + u, & + auv, & + buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m)) + + if (LPROF) call stop_timing(id, 'tl_bdy_lyr_alg') + +end subroutine tl_bdy_lyr_alg + +end module tl_bdy_lyr_alg_mod diff --git a/science/linear/source/algorithm/linear_physics/tl_physics_alg.x90 b/science/linear/source/algorithm/linear_physics/tl_physics_alg.x90 new file mode 100644 index 000000000..5289776ec --- /dev/null +++ b/science/linear/source/algorithm/linear_physics/tl_physics_alg.x90 @@ -0,0 +1,135 @@ +!----------------------------------------------------------------------------- +! (c) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be brief. +!----------------------------------------------------------------------------- +!> @brief Wrapper for tangent linear physics code +module tl_physics_alg_mod + + use constants_mod, only: r_def + use driver_modeldb_mod, only: modeldb_type + use field_mod, only: field_type + use derived_config_mod, only: bundle_size + use field_indices_mod, only: igh_u + use timing_mod, only: start_timing, stop_timing, tik, LPROF + use mesh_mod, only: mesh_type + use fs_continuity_mod, only: W2 + use sci_geometric_constants_mod, only: get_da_at_w2 + use sci_fem_constants_mod, only: get_mass_matrix_fe + use sci_enforce_bc_kernel_mod, only: enforce_bc_kernel_type + use matrix_vector_kernel_mod, only: matrix_vector_kernel_type + use tl_bdy_lyr_alg_mod, only: tl_bdy_lyr_alg + use sci_mass_matrix_solver_alg_mod, only: mass_matrix_solver_alg + use sci_field_bundle_builtins_mod, only: clone_bundle, copy_bundle, set_bundle_scalar + use operator_mod, only: operator_type + + implicit none + + private + public :: tl_physics_alg + +contains + +!> @brief Wrapper for tangent linear physics code, currently just tl_bdy_lyr_alg +!> @param[in,out] modeldb Structure containing the model state +!> @param[in,out] u The TL model u field to be incremented +!> @param[in,out] state_star TL model prognostic fields for physics calculations +!> @param[in,out] rhs_phys Residuals +!> @param[in] state The current TL model prognostic fields +!> @param[in] rhs_n Residuals +!> @param[in] rhs_np1 Residuals +!> @param[in] rhs_adv Advective terms +!> @param[in] ls_state Lin state for Prognostic model state +!> @param[in] mesh The current mesh +!> @param[in] dt The TL model timestep length +subroutine tl_physics_alg(modeldb, & + u, & + state_star, & + rhs_phys, & + rhs_np1, & + rhs_n, & + state, & + rhs_adv, & + ls_state, & + mesh, & + dt) + + implicit none + + type(modeldb_type), target, intent(inout) :: modeldb + type(field_type), intent(inout) :: u + type(field_type), intent(inout) :: state_star(bundle_size) + type(field_type), intent(inout) :: rhs_phys(bundle_size) + type(field_type), intent(in) :: state(bundle_size) + type(field_type), intent(in) :: rhs_n(bundle_size) + type(field_type), intent(in) :: rhs_np1(bundle_size) + type(field_type), intent(in) :: rhs_adv(bundle_size) + type(field_type), intent(in) :: ls_state(bundle_size) + type(mesh_type), pointer, intent(in) :: mesh + real(kind=r_def), intent(in) :: dt + + type(field_type) :: u_bl_inc + type(field_type) :: u_bl_inc_flux + type(field_type) :: du + type(field_type) :: u_star + type(field_type) :: u_star_physical + type(field_type) :: rhsu_np1 + + type(operator_type), pointer :: mm_vel + type(field_type), pointer :: dA + + integer(kind=tik) :: id + + if (LPROF) call start_timing(id, 'tl_physics_alg') + + mm_vel => get_mass_matrix_fe(W2, mesh%get_id()) + + ! Run linear boundary layer scheme to compute increment to u perturbation + + call u%copy_field_properties( u_bl_inc ) + call u%copy_field_properties( u_bl_inc_flux ) + call u%copy_field_properties( du ) + call u%copy_field_properties( u_star ) + call u%copy_field_properties( u_star_physical ) + call rhs_adv(igh_u)%copy_field_properties( rhsu_np1 ) + + ! Compute u_star = u_np1 + du + ! where du = M^-1(-rhs_np1 + rhs_n + rhs_a) + ! This mirrors the calc_phys_predictors_alg in gungho + call du%initialise( rhs_adv(igh_u)%get_function_space() ) + call rhsu_np1%initialise( rhs_adv(igh_u)%get_function_space() ) + call invoke( setval_c( du, 0.0_r_def ), & + aX_plus_Y( rhsu_np1, -1.0_r_def, rhs_np1(igh_u), rhs_n(igh_u) ), & + inc_X_plus_Y( rhsu_np1, rhs_adv(igh_u) ) ) + + call mass_matrix_solver_alg( du, rhsu_np1 ) + + call invoke( X_plus_Y( u_star, du, state(igh_u) ) ) + + ! u_star_physical = u_star / dA + ! i.e., divide u_star from boundary layer by dA to transform from flux to velocity + dA => get_da_at_w2(mesh%get_id()) + call invoke( x_divideby_y ( u_star_physical, u_star, dA ) ) + + ! For convenience place u_star_physical as igh_u component of state_star + call clone_bundle( state,state_star, bundle_size ) + call copy_bundle( state, state_star, bundle_size ) + call invoke( setval_x( state_star(igh_u), u_star_physical ) ) + + ! u_bl_inc computed from state_star(igh_u) + call tl_bdy_lyr_alg( modeldb, u_bl_inc, state_star(igh_u), ls_state, dt ) + + ! u_bl_inc_flux = u_bl_inc * dA + ! i.e., multiply by cell face area dA to transform from velocity to flux + call invoke( x_times_y( u_bl_inc_flux, u_bl_inc, dA ) ) + + call set_bundle_scalar( 0.0_r_def, rhs_phys, bundle_size ) + call invoke( name="update_rhs_phys_from_fast_physics", & + matrix_vector_kernel_type( rhs_phys(igh_u), u_bl_inc_flux, mm_vel ), & + enforce_bc_kernel_type( rhs_phys(igh_u) ) ) + + if (LPROF) call stop_timing(id, 'tl_physics_alg') + +end subroutine tl_physics_alg + +end module tl_physics_alg_mod diff --git a/science/linear/source/algorithm/timestepping/tl_rk_alg_timestep_mod.x90 b/science/linear/source/algorithm/timestepping/tl_rk_alg_timestep_mod.x90 index 30d391f99..79a481b53 100644 --- a/science/linear/source/algorithm/timestepping/tl_rk_alg_timestep_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_rk_alg_timestep_mod.x90 @@ -82,8 +82,8 @@ module tl_rk_alg_timestep_mod use moist_dyn_mod, only: num_moist_factors, gas_law use mr_indices_mod, only: nummr - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use sci_field_minmax_alg_mod, only: log_field_minmax @@ -255,8 +255,9 @@ contains ! Fields with larger halos type(field_type) :: ls_exner_big_halo, & exner_big_halo + integer(tik) :: id - if ( subroutine_timers ) call timer('tl_rk_alg') + if ( LPROF ) call start_timing( id, 'tl_runge_kutta_timestep' ) cast_dt = real(model_clock%get_seconds_per_step(), r_def) @@ -508,7 +509,7 @@ contains nullify( geopotential, chi, panel_id, m3_inv, & mesh, reference_element, qr ) - if ( subroutine_timers ) call timer('tl_rk_alg') + if ( LPROF ) call stop_timing( id, 'tl_runge_kutta_timestep' ) end subroutine tl_rk_alg_step diff --git a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 index c4bfedbd2..d912604f0 100644 --- a/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 +++ b/science/linear/source/algorithm/timestepping/tl_si_timestep_alg_mod.x90 @@ -25,13 +25,12 @@ module tl_si_timestep_alg_mod use_wavedynamics, & si_momentum_equation, & exner_from_eos - - use io_config_mod, only: subroutine_timers, & - write_conservation_diag + use io_config_mod, only: write_conservation_diag use linear_config_mod, only: fixed_ls, & l_stabilise_bl, & n_bl_levels_to_stabilise, & max_bl_stabilisation + use linear_physics_config_mod, only: l_boundary_layer use mixed_solver_config_mod, only: guess_np1, & reference_reset_time use timestepping_config_mod, only: alpha, & @@ -97,6 +96,8 @@ module tl_si_timestep_alg_mod use map_physics_fields_alg_mod, only: map_physics_fields_alg + use tl_physics_alg_mod, only: tl_physics_alg + ! Moisture species use mr_indices_mod, only: nummr, imr_v, imr_cl use moist_dyn_mod, only: num_moist_factors, gas_law @@ -107,7 +108,7 @@ module tl_si_timestep_alg_mod ! Mixing settings use mixing_config_mod, only: smagorinsky - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, tik, LPROF implicit none @@ -123,6 +124,7 @@ module tl_si_timestep_alg_mod type( field_type ), allocatable :: state_initial(:) type( field_type ), allocatable :: state_n(:) type( field_type ), allocatable :: state_after_slow(:) + type( field_type ), allocatable :: state_star(:) type( field_type ), allocatable :: advected_state(:) type( field_type ), allocatable :: mr_n(:) type( field_type ), allocatable :: mr_inc(:) @@ -130,6 +132,7 @@ module tl_si_timestep_alg_mod type( field_type ), allocatable :: rhs_n(:) type( field_type ), allocatable :: rhs_np1(:) type( field_type ), allocatable :: rhs_adv(:) + type( field_type ), allocatable :: rhs_phys(:) ! Linearisation state type( field_type ), allocatable :: ls_state(:) @@ -220,10 +223,12 @@ contains allocate(state_initial(bundle_size)) allocate(state_n(bundle_size)) allocate(state_after_slow(bundle_size)) + allocate(state_star(bundle_size)) allocate(advected_state(bundle_size)) allocate(rhs_n(bundle_size)) allocate(rhs_np1(bundle_size)) allocate(rhs_adv(bundle_size)) + allocate(rhs_phys(bundle_size)) allocate(mr_n(nummr)) allocate(mr_after_slow(nummr)) allocate(mr_inc(nummr)) @@ -273,6 +278,7 @@ contains call clone_bundle(state, rhs_n, bundle_size) call clone_bundle(state, rhs_np1, bundle_size) call clone_bundle(state, rhs_adv, bundle_size) + call clone_bundle(state, rhs_phys, bundle_size) call clone_bundle(state, ls_state, bundle_size) call clone_bundle(state, ls_state_n, bundle_size) @@ -396,8 +402,9 @@ contains ! Configuration type( namelist_type ), pointer :: mixed_solver_nml real( kind=r_def ) :: mixed_solver_a_tol + integer(tik) :: id - if ( subroutine_timers ) call timer('semi_implicit_timestep_alg') + if ( LPROF ) call start_timing( id, 'tl_semi_implicit_timestep' ) cast_dt = real(modeldb%clock%get_seconds_per_step(), r_def) @@ -697,6 +704,8 @@ contains moist_dyn, ls_state_n, ls_moist_dyn_itns(:, 1,1), & .false., .false., model_clock=modeldb%clock ) + call invoke(setval_c( rhs_np1(igh_u), 0.0_r_def )) + call copy_bundle(state_after_slow, advected_state, bundle_size) if ( .not. si_momentum_equation ) then ! Predictor of the wind field (u-beta*dt*rhs) to be advected if using @@ -739,6 +748,38 @@ contains dg_inc_matrix_vector_kernel_type(rhs_adv(igh_t), & theta_fv_inc, mm_wt) ) + ! Previously tl_rhs_alg was called within each inner loop. + ! It still is called there for inner_iterations > 1. + ! For the first inner loop, it needs to be called before entering. + ! This is because rhs_np1 is used to calculate u_star in tl_bdy_lyr_alg. + if (use_wavedynamics) then + call tl_rhs_alg( rhs_np1, & + -varalpha*cast_dt, & + state, & + state, & + moist_dyn, & + ls_state_itns( :, ls_outer, 1 ), & + ls_moist_dyn_itns( :, ls_outer, 1 ), & + .true., & + dlayer_on, & + modeldb%clock ) + end if + + if (l_boundary_layer) then + ! Linear boundary layer scheme is currently the only linear physics scheme + call tl_physics_alg( modeldb, & + u, & + state_star, & + rhs_phys, & + rhs_np1, & + rhs_n, & + state, & + rhs_adv, & + ls_state_itns(:,ls_outer,1), & + mesh, & + cast_dt ) + end if ! l_boundary_layer + if (use_wavedynamics) then ! Use advective update to guess n+1 level scalar fieldsgv . @@ -762,16 +803,19 @@ contains !-------------------------------------------------------------------- ! Compute the time-level n+1 dynamics terms !-------------------------------------------------------------------- - call tl_rhs_alg(rhs_np1, & - -varalpha*cast_dt, & - state, & - state, & - moist_dyn, & - ls_state_itns(:, ls_outer, ls_inner), & - ls_moist_dyn_itns(:, ls_outer, ls_inner), & - .true., & - dlayer_on, & - modeldb%clock) + ! Only call tl_rhs_alg if inner > 1 as for inner===1 it is already called early (see comment above) + if (inner > 1) then + call tl_rhs_alg(rhs_np1, & + -varalpha*cast_dt, & + state, & + state, & + moist_dyn, & + ls_state_itns(:, ls_outer, ls_inner), & + ls_moist_dyn_itns(:, ls_outer, ls_inner), & + .true., & + dlayer_on, & + modeldb%clock) + end if !-------------------------------------------------------------------- ! Compute the LAM LBCs and RHS @@ -788,6 +832,7 @@ contains !-------------------------------------------------------------------- call bundle_axpy(-1.0_r_def, rhs_np1, rhs_n, rhs_np1, bundle_size) call add_bundle(rhs_np1, rhs_adv, rhs_np1, bundle_size) + if (l_boundary_layer) call add_bundle(rhs_np1, rhs_phys, rhs_np1, bundle_size) if ( limited_area ) then call log_event( "No limited area for Tangent linear", LOG_LEVEL_ERROR ) @@ -891,7 +936,7 @@ contains nullify( mm_wt, mm_vel, qr ) - if ( subroutine_timers ) call timer('semi_implicit_timestep_alg') + if ( LPROF ) call stop_timing( id, 'tl_semi_implicit_timestep' ) end subroutine tl_semi_implicit_alg_step @@ -910,10 +955,12 @@ contains if (allocated(state_initial)) deallocate(state_initial) if (allocated(state_n)) deallocate(state_n) if (allocated(state_after_slow)) deallocate(state_after_slow) + if (allocated(state_star)) deallocate(state_star) if (allocated(advected_state)) deallocate(advected_state) if (allocated(rhs_n)) deallocate(rhs_n) if (allocated(rhs_np1)) deallocate(rhs_np1) if (allocated(rhs_adv)) deallocate(rhs_adv) + if (allocated(rhs_phys)) deallocate(rhs_phys) if (allocated(mr_n)) deallocate(mr_n) if (allocated(mr_after_slow)) deallocate(mr_after_slow) if (allocated(mr_inc)) deallocate(mr_inc) diff --git a/science/linear/source/algorithm/transport/common/tl_end_of_transport_step_alg_mod.x90 b/science/linear/source/algorithm/transport/common/tl_end_of_transport_step_alg_mod.x90 index 0cda7d6a0..d688438dd 100644 --- a/science/linear/source/algorithm/transport/common/tl_end_of_transport_step_alg_mod.x90 +++ b/science/linear/source/algorithm/transport/common/tl_end_of_transport_step_alg_mod.x90 @@ -17,7 +17,6 @@ module tl_end_of_transport_step_alg_mod use fs_continuity_mod, only: W2, W2H, W2V use function_space_mod, only: function_space_type use function_space_collection_mod, only: function_space_collection - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, LOG_LEVEL_ERROR use mesh_mod, only: mesh_type use mesh_collection_mod, only: mesh_collection diff --git a/science/linear/source/algorithm/transport/control/tl_moist_mr_transport_alg_mod.x90 b/science/linear/source/algorithm/transport/control/tl_moist_mr_transport_alg_mod.x90 index bf534b144..8291318e1 100644 --- a/science/linear/source/algorithm/transport/control/tl_moist_mr_transport_alg_mod.x90 +++ b/science/linear/source/algorithm/transport/control/tl_moist_mr_transport_alg_mod.x90 @@ -10,11 +10,11 @@ module tl_moist_mr_transport_alg_mod use constants_mod, only: i_def, r_def use sci_enforce_lower_bound_kernel_mod, only: enforce_lower_bound_kernel_type use field_mod, only: field_type - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR use mr_indices_mod, only: nummr - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use tl_transport_controller_mod, only: tl_transport_controller_type use transport_enumerated_types_mod, only: equation_form_advective, & equation_form_conservative @@ -61,8 +61,9 @@ contains ! Internal variables integer(kind=i_def) :: imr + integer(tik) :: id - if ( subroutine_timers ) call timer('tl moist mixing ratio transport') + if ( LPROF ) call start_timing( id, 'tl_moist_mixing_ratio_transport' ) ! Choose form of transport equation select case ( transport_metadata%get_equation_form() ) @@ -106,7 +107,7 @@ contains call invoke( setval_X(mr_out(imr), mr_in(imr)) ) end do - if ( subroutine_timers ) call timer('tl moist mixing ratio transport') + if ( LPROF ) call stop_timing( id, 'tl_moist_mixing_ratio_transport' ) end subroutine tl_moist_mr_transport_alg diff --git a/science/linear/source/algorithm/transport/control/tl_split_transport_mod.x90 b/science/linear/source/algorithm/transport/control/tl_split_transport_mod.x90 new file mode 100644 index 000000000..779dd5b5a --- /dev/null +++ b/science/linear/source/algorithm/transport/control/tl_split_transport_mod.x90 @@ -0,0 +1,333 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief Tangent linear version of split_transport + +module tl_split_transport_mod + + use constants_mod, only: i_def, r_tran + use r_tran_field_mod, only: r_tran_field_type + use log_mod, only: log_event, LOG_LEVEL_ERROR + use split_transport_utils_mod, only: get_splitting_direction, & + get_splitting_fraction, & + get_num_split_steps + use split_transport_mod, only: split_transport_field + + ! Transport control infrastructure + use transport_controller_mod, only: transport_controller_type + use tl_transport_controller_mod, only: tl_transport_controller_type + use transport_counter_mod, only: transport_counter_type + use transport_enumerated_types_mod, only: direction_h, & + direction_v, & + split_method_null, & + split_method_mol, & + split_method_ffsl, & + split_method_sl, & + equation_form_conservative, & + equation_form_advective, & + equation_form_consistent + use transport_metadata_mod, only: transport_metadata_type + + ! Algorithms + use end_of_transport_step_alg_mod, only: end_of_conservative_step_alg, & + end_of_consistent_step_alg, & + end_of_advective_step_alg + use linear_config_mod, only: transport_efficiency + + implicit none + + private + + public :: tl_split_transport_control + public :: tl_split_transport_field + +contains + + !============================================================================= + !> @brief Controls vertical/horizontal split transport. + !> @details Manages the vertical/horizontal splitting of the split transport + !! scheme by choosing the splitting type and calling the individual + !! vertical and horizontal split components. + !> @param[in,out] field_np1 ACTIVE Field to return at end + !> @param[in] field_n ACTIVE Field at the start + !> @param[in] ls_field_n PASSIVE LS Field at the start + !> @param[in,out] tl_transport_controller + !! Encapsulating object containing the + !! transport counter and precomputations + subroutine tl_split_transport_control(field_np1, field_n, ls_field_n, & + tl_transport_controller) + + implicit none + + ! Arguments + type(r_tran_field_type), intent(inout) :: field_np1 + type(r_tran_field_type), target, intent(in) :: field_n + type(r_tran_field_type), target, intent(in) :: ls_field_n + type(tl_transport_controller_type), intent(inout) :: tl_transport_controller + + ! Internal variables + integer(kind=i_def) :: num_split_steps + integer(kind=i_def) :: split_step_count + type(r_tran_field_type), allocatable :: ls_field_np1(:) + type(r_tran_field_type), target :: field_tmp + type(r_tran_field_type), pointer :: field_ptr + type(transport_counter_type), pointer :: transport_counter + type(transport_counter_type), pointer :: ls_transport_counter + type(transport_metadata_type), pointer :: transport_metadata + type(transport_controller_type), pointer :: pert_transport_controller + type(transport_controller_type), pointer :: ls_transport_controller + real(kind=r_tran) :: dt_substep + integer(kind=i_def) :: num_substeps + + ! ------------------------------------------------------------------------ ! + ! NONLINEAR (LS) + ! ------------------------------------------------------------------------ ! + + ls_transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() + transport_metadata => ls_transport_controller%get_transport_metadata() + ls_transport_counter => ls_transport_controller%get_transport_counter() + + ! Initialise fields + num_split_steps = get_num_split_steps(transport_metadata%get_splitting()) + allocate(ls_field_np1(num_split_steps + 1)) + do split_step_count = 1, num_split_steps + 1 + call field_n%copy_field_properties(ls_field_np1(split_step_count)) + end do + + if ( .not. transport_efficiency ) then + + ! When we have multiple split steps, we need an intermediate field for the + ! field at the start of each substep + ! field_ptr points to the field at the start of each split step + call invoke( setval_X(ls_field_np1(1), ls_field_n) ) + + if (num_split_steps > 1) then + call field_n%copy_field_properties(field_tmp) + call invoke( setval_X(field_tmp, ls_field_n) ) + field_ptr => field_tmp + else + field_ptr => ls_field_n + end if + + do split_step_count = 1, num_split_steps + call split_transport_field( ls_field_np1(split_step_count+1), & + field_ptr, & + ls_transport_controller & + ) + + if (split_step_count < num_split_steps) then + call invoke( setval_X(field_tmp, ls_field_np1(split_step_count+1) ) ) + + ! Increment split step counter + call ls_transport_counter%inc_split_step_counter() + end if + end do + + else + ! Assume that the linearisation state does not evolve during the split transport + do split_step_count = 1, num_split_steps + 1 + call invoke( setval_X(ls_field_np1(split_step_count), ls_field_n) ) + end do + end if + + dt_substep = ls_transport_counter%get_dt_substep() + num_substeps = ls_transport_counter%get_num_substeps() + call ls_transport_counter%initialise(transport_metadata, dt_substep, num_substeps ) + + ! ------------------------------------------------------------------------ ! + ! LINEAR + ! ------------------------------------------------------------------------ ! + + pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_metadata => pert_transport_controller%get_transport_metadata() + transport_counter => pert_transport_controller%get_transport_counter() + + ! Initialise fields + num_split_steps = get_num_split_steps(transport_metadata%get_splitting()) + + ! When we have multiple split steps, we need an intermediate field for the + ! field at the start of each substeps + ! field_ptr points to the field at the start of each split step + if (num_split_steps > 1) then + call field_n%copy_field_properties(field_tmp) + call invoke( setval_X(field_tmp, field_n) ) + field_ptr => field_tmp + else + field_ptr => field_n + end if + + do split_step_count = 1, num_split_steps + + call tl_split_transport_field( & + field_np1, field_ptr, ls_field_np1(split_step_count), & + tl_transport_controller & + ) + + if (split_step_count < num_split_steps) then + call invoke( setval_X(field_tmp, field_np1 ) ) + + ! Increment split step counter + call transport_counter%inc_split_step_counter() + call ls_transport_counter%inc_split_step_counter() + end if + + end do + + deallocate( ls_field_np1 ) + + end subroutine tl_split_transport_control + + !============================================================================= + !> @brief Does either vertical or horizontal transport of a field. + !> @details Performs a vertical or horizontal transport step, solving the + !! transport equation for a (multidata) field. + !> @param[in,out] field_np1 ACTIVE Field to return at end + !> @param[in] field_n ACTIVE Field at the start + !> @param[in] ls_field_n PASSIVE Field at the start + !> @param[in,out] tl_transport_controller + !! Encapsulating object containing the + !! transport counter and precomputations + subroutine tl_split_transport_field(field_np1, field_n, ls_field_n, tl_transport_controller) + + use tl_mol_conservative_alg_mod, only: tl_mol_conservative_alg + use tl_mol_advective_alg_mod, only: tl_mol_advective_alg + + implicit none + + ! Arguments + type(r_tran_field_type), intent(inout) :: field_np1 + type(r_tran_field_type), intent(in) :: field_n + type(r_tran_field_type), intent(in) :: ls_field_n + type(tl_transport_controller_type), intent(inout) :: tl_transport_controller + + ! Internal variables + integer(kind=i_def) :: method, direction + type(transport_counter_type), pointer :: transport_counter + type(transport_metadata_type), pointer :: transport_metadata + type(transport_controller_type), pointer :: pert_transport_controller + + pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_counter => pert_transport_controller%get_transport_counter() + transport_metadata => pert_transport_controller%get_transport_metadata() + + ! -------------------------------------------------------------------------! + ! Set up method based on direction + ! -------------------------------------------------------------------------! + direction = get_splitting_direction( & + transport_metadata%get_splitting(), & + transport_counter%get_split_step_of_substep_counter() & + ) + + select case ( direction ) + case ( direction_h ) + method = transport_metadata%get_horizontal_method() + case ( direction_v ) + method = transport_metadata%get_vertical_method() + case default + call log_event('Split transport direction not recognised', LOG_LEVEL_ERROR) + end select + + ! -------------------------------------------------------------------------! + ! Choose method, and then choose equation + ! -------------------------------------------------------------------------! + select case ( method ) + + ! -------------------------------------------------------------------------! + ! Null step + ! -------------------------------------------------------------------------! + case ( split_method_null ) + call log_event( & + 'TL: Split method null not coded', & + LOG_LEVEL_ERROR & + ) + + ! -------------------------------------------------------------------------! + ! Method of Lines step + ! -------------------------------------------------------------------------! + case ( split_method_mol ) + ! Choose form of transport equation + select case ( transport_metadata%get_equation_form() ) + case ( equation_form_conservative ) + call tl_mol_conservative_alg( & + field_np1, field_n, ls_field_n, tl_transport_controller & + ) + case ( equation_form_advective ) + call tl_mol_advective_alg( & + field_np1, field_n, ls_field_n, tl_transport_controller & + ) + case ( equation_form_consistent ) + call log_event( & + 'TL: MoL Consistent not coded yet', & + LOG_LEVEL_ERROR & + ) + case default + call log_event( & + 'Trying to solve unrecognised form of transport equation', & + LOG_LEVEL_ERROR & + ) + + end select + + ! -------------------------------------------------------------------------! + ! Flux-Form Semi-Lagrangian step + ! -------------------------------------------------------------------------! + case ( split_method_ffsl ) + ! All equation forms have the same control method + call log_event( & + 'TL: FFSL not coded yet', & + LOG_LEVEL_ERROR & + ) + ! -------------------------------------------------------------------------! + ! Semi-Lagrangian step + ! -------------------------------------------------------------------------! + case ( split_method_sl ) + ! Choose direction + select case ( direction ) + + case ( direction_h ) + ! Horizontal SL only for advective form + if ( transport_metadata%get_equation_form() /= equation_form_advective ) then + call log_event( & + 'Horizontal semi-Lagrangian is only for advective form', & + LOG_LEVEL_ERROR & + ) + end if + call log_event( & + 'TL: Horizontal SL not coded yet', & + LOG_LEVEL_ERROR & + ) + + case ( direction_v ) + ! Choose form of transport equation for vertical + select case ( transport_metadata%get_equation_form() ) + + case ( equation_form_conservative ) + call log_event( & + 'TL: Vertical SL conservative not coded yet', & + LOG_LEVEL_ERROR & + ) + case ( equation_form_advective ) + call log_event( & + 'TL: Vertical SL advective not coded yet', & + LOG_LEVEL_ERROR & + ) + case default + call log_event( & + 'Trying to solve unrecognised form of transport equation', & + LOG_LEVEL_ERROR & + ) + end select + end select + + case default + call log_event( & + 'Trying to transport with unrecognised scheme', & + LOG_LEVEL_ERROR & + ) + end select + + end subroutine tl_split_transport_field + +end module tl_split_transport_mod diff --git a/science/linear/source/algorithm/transport/control/tl_theta_transport_alg_mod.x90 b/science/linear/source/algorithm/transport/control/tl_theta_transport_alg_mod.x90 index 157823b27..bcc06de5e 100644 --- a/science/linear/source/algorithm/transport/control/tl_theta_transport_alg_mod.x90 +++ b/science/linear/source/algorithm/transport/control/tl_theta_transport_alg_mod.x90 @@ -17,7 +17,6 @@ module tl_theta_transport_alg_mod use log_mod, only: log_event, & LOG_LEVEL_ERROR use operator_mod, only: operator_type - use timer_mod, only: timer use timestepping_config_mod, only: time_method => method, & method_semi_implicit use tl_transport_field_mod, only: tl_transport_field diff --git a/science/linear/source/algorithm/transport/control/tl_transport_control_alg_mod.x90 b/science/linear/source/algorithm/transport/control/tl_transport_control_alg_mod.x90 index 337b471df..be30bb11b 100644 --- a/science/linear/source/algorithm/transport/control/tl_transport_control_alg_mod.x90 +++ b/science/linear/source/algorithm/transport/control/tl_transport_control_alg_mod.x90 @@ -66,8 +66,8 @@ contains use tl_theta_transport_alg_mod, only: tl_theta_transport_alg use tl_transport_field_mod, only: tl_transport_field use tl_wind_transport_alg_mod, only: tl_wind_transport_alg - use io_config_mod, only: subroutine_timers - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF implicit none @@ -88,11 +88,12 @@ contains ! Internal variables type(field_type) :: fields_np1(bundle_size) logical(kind=l_def) :: cheap_update_step + integer(tik) :: id type(transport_metadata_type), pointer :: transport_metadata type(tl_transport_controller_type) :: tl_transport_controller - if ( subroutine_timers ) call timer('tl_transport_control') + if ( LPROF ) call start_timing( id, 'tl_transport_control' ) ! ======================================================================== ! ! Pre-transport initialisation tasks @@ -182,7 +183,7 @@ contains call tl_transport_controller%finalise() - if ( subroutine_timers ) call timer('tl_transport_control') + if ( LPROF ) call stop_timing( id, 'tl_transport_control' ) end subroutine tl_transport_control_alg diff --git a/science/linear/source/algorithm/transport/control/tl_transport_field_mod.f90 b/science/linear/source/algorithm/transport/control/tl_transport_field_mod.f90 index 17016206a..5fd0a5b02 100644 --- a/science/linear/source/algorithm/transport/control/tl_transport_field_mod.f90 +++ b/science/linear/source/algorithm/transport/control/tl_transport_field_mod.f90 @@ -21,6 +21,7 @@ module tl_transport_field_mod equation_form_advective use tl_mol_conservative_alg_mod, only: tl_mol_conservative_alg use tl_mol_advective_alg_mod, only: tl_mol_advective_alg + use tl_split_transport_mod, only: tl_split_transport_control use transport_controller_mod, only: transport_controller_type use tl_transport_controller_mod, only: tl_transport_controller_type use transport_counter_mod, only: transport_counter_type @@ -121,10 +122,8 @@ subroutine tl_transport_field(field_np1, field_n, ls_field_n, & ! Some split horizontal/vertical transport scheme ! -------------------------------------------------------------------------! case ( scheme_split ) - call log_event( & - 'Split transport not implemented for tangent-linear app', & - LOG_LEVEL_ERROR & - ) + call tl_split_transport_control(field_np1, field_n, ls_field_n, & + tl_transport_controller) case default call log_event( & diff --git a/science/linear/source/algorithm/transport/control/tl_wind_transport_alg_mod.x90 b/science/linear/source/algorithm/transport/control/tl_wind_transport_alg_mod.x90 index 9c8a74613..db3cb2f03 100644 --- a/science/linear/source/algorithm/transport/control/tl_wind_transport_alg_mod.x90 +++ b/science/linear/source/algorithm/transport/control/tl_wind_transport_alg_mod.x90 @@ -21,7 +21,6 @@ module tl_wind_transport_alg_mod use function_space_mod, only: function_space_type use function_space_collection_mod, only: function_space_collection use sci_geometric_constants_mod, only: get_coordinates, get_panel_id - use io_config_mod, only: subroutine_timers use log_mod, only: log_event, & LOG_LEVEL_ERROR, & LOG_LEVEL_INFO @@ -30,7 +29,8 @@ module tl_wind_transport_alg_mod get_project_zdot_to_w2 use mesh_mod, only: mesh_type use operator_mod, only: operator_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF use transport_config_mod, only: broken_w2_projection use tl_transport_controller_mod, only: tl_transport_controller_type use tl_transport_field_mod, only: tl_transport_field @@ -96,8 +96,9 @@ contains type(function_space_type), pointer :: w3_fs type(function_space_type), pointer :: w2_fs type(function_space_type), pointer :: w2b_fs + integer(tik) :: id - if ( subroutine_timers ) call timer('tl wind transport') + if ( LPROF ) call start_timing( id, 'tl_wind_transport' ) ! ------------------------------------------------------------------------ ! ! Semi-implicit formulation @@ -238,7 +239,7 @@ contains end if ! si_momentum_equation - if ( subroutine_timers ) call timer('tl wind transport') + if ( LPROF ) call stop_timing( id, 'tl_wind_transport' ) end subroutine tl_wind_transport_alg diff --git a/science/linear/source/algorithm/transport/mol/tl_mol_advective_alg_mod.x90 b/science/linear/source/algorithm/transport/mol/tl_mol_advective_alg_mod.x90 index a1a34919f..e85d71036 100644 --- a/science/linear/source/algorithm/transport/mol/tl_mol_advective_alg_mod.x90 +++ b/science/linear/source/algorithm/transport/mol/tl_mol_advective_alg_mod.x90 @@ -28,6 +28,7 @@ module tl_mol_advective_alg_mod ! Configuration use transport_config_mod, only: runge_kutta_method + use linear_config_mod, only: transport_efficiency implicit none @@ -58,7 +59,9 @@ contains ! Internal variables integer(kind=i_def) :: stage, s, direction integer(kind=i_def) :: nstage, substep + integer(kind=i_def) :: ls_nstage, ls_substep integer(kind=i_def) :: number_substeps + integer(kind=i_def) :: ls_stage, ls_number_substeps integer(kind=i_def) :: step integer(kind=i_def) :: splitting real(kind=r_def) :: dt_mol_substep @@ -73,7 +76,10 @@ contains type(field_type), allocatable :: rk_field(:) real(kind=r_def), allocatable :: rk_weights(:,:) type(transport_metadata_type), pointer :: transport_metadata + type(transport_metadata_type), pointer :: ls_transport_metadata type(transport_counter_type), pointer :: transport_counter + type(transport_counter_type), pointer :: ls_transport_counter + type(transport_controller_type), pointer :: transport_controller type(transport_controller_type), pointer :: ls_transport_controller type(transport_controller_type), pointer :: pert_transport_controller type(wind_precomputations_type), pointer :: ls_wind_precomputations @@ -83,10 +89,17 @@ contains ! Extract transport objects and initialise temporary fields ! ------------------------------------------------------------------------ ! mesh => field%get_mesh() + + transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() ls_transport_controller => tl_transport_controller%get_ls_wind_pert_rho_controller() pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_metadata => pert_transport_controller%get_transport_metadata() + ls_transport_metadata => transport_controller%get_transport_metadata() + transport_counter => pert_transport_controller%get_transport_counter() + ls_transport_counter => transport_controller%get_transport_counter() + ls_wind_precomputations => ls_transport_controller%get_wind_precomputations() pert_wind_precomputations => pert_transport_controller%get_wind_precomputations() @@ -107,13 +120,23 @@ contains call field_n%initialise(field%get_function_space()) call get_rk_transport_weights(nstage, rk_weights, runge_kutta_method) + + if (transport_efficiency) then + ls_number_substeps = 1 + ls_nstage =1 + else + ls_number_substeps = number_substeps + ls_nstage = nstage + end if allocate( rk_field(nstage) ) - allocate( stored_ls_field(number_substeps, nstage) ) + allocate( stored_ls_field(ls_number_substeps, ls_nstage) ) do stage = 1, nstage call rk_field(stage)%initialise(field%get_function_space()) - do substep = 1, number_substeps - call stored_ls_field(substep, stage)%initialise(field%get_function_space()) + end do + do ls_stage = 1, ls_nstage + do ls_substep = 1, ls_number_substeps + call stored_ls_field(ls_substep, ls_stage)%initialise(field%get_function_space()) end do end do call rhs_field%initialise( field%get_function_space() ) @@ -130,19 +153,23 @@ contains ! array for each substep and each RK stage to use in the perturbation !--------------------------------------------------------------------------! + if (transport_efficiency) then + call invoke( setval_X( stored_ls_field(1,1), ls_field_np1)) + else + ! Perform the number of rk-stages and substeps required - do substep = 1, number_substeps + do substep = 1, ls_number_substeps ! Reset field_n ready for the this substep call ls_field_np1%copy_field_properties(ls_field_n) call invoke( setval_X(ls_field_n, ls_field_np1) ) - do stage = 1, nstage + do stage = 1, ls_nstage ! Store values for use in the perturbation code. This is done before ! advecting so as to pick up the correct linearisation state call invoke( setval_X(stored_ls_field(substep, stage), ls_field_np1) ) - final_rk_stage = ( stage == nstage ) + final_rk_stage = ( stage == ls_nstage ) ! Compute the field for this stage: ! rhs_field = sum(s=1,stage): a(stage,s)*field^(s) @@ -153,9 +180,9 @@ contains end do ! Compute update: rhs = u.grad(rhs_field) - call advective_and_flux_alg(dummy, rhs, rhs_field, ls_field_n, & - ls_advecting_wind, direction, & - transport_metadata, final_rk_stage, & + call advective_and_flux_alg(dummy, rhs, rhs_field, ls_field_n, & + ls_advecting_wind, direction, & + ls_transport_metadata, final_rk_stage, & dt_mol_substep, .false., .true. ) ! Update field: f = f^n - dt*rhs @@ -165,10 +192,12 @@ contains end do ! End of step: if necessary enforce min val and overwrite in blending zone - call end_of_advective_step_alg( & - ls_field_np1, ls_field_n, transport_counter, transport_metadata & + call end_of_advective_step_alg( & + ls_field_np1, ls_field_n, ls_transport_counter, ls_transport_metadata & ) + end if + ! -------------------------------------------------------------------------- ! Perturbation ! @@ -177,15 +206,28 @@ contains ! linearisation stage stage !--------------------------------------------------------------------------- + ! Perform the number of rk-stages and substeps required do substep = 1, number_substeps + if (transport_efficiency) then + ls_substep = 1 + else + ls_substep = substep + end if + ! Reset field_n ready for the this substep call field_np1%copy_field_properties(field_n) call invoke( setval_X(field_n, field_np1) ) do stage = 1, nstage + if (transport_efficiency) then + ls_stage = 1 + else + ls_stage = stage + end if + final_rk_stage = ( stage == nstage ) ! Compute the field for this stage: @@ -199,7 +241,7 @@ contains ! Compute update: rhs = u.grad(rhs_field) call tl_advective_and_flux_alg( & dummy, dummy, rhs, rhs_field, advecting_wind, & - stored_ls_field(substep, stage), ls_advecting_wind, & + stored_ls_field(ls_substep, ls_stage), ls_advecting_wind, & direction, transport_metadata, final_rk_stage, dt_mol_substep, & .false., .true. & ) diff --git a/science/linear/source/algorithm/transport/mol/tl_mol_conservative_alg_mod.x90 b/science/linear/source/algorithm/transport/mol/tl_mol_conservative_alg_mod.x90 index b4563234e..2b83dbe30 100644 --- a/science/linear/source/algorithm/transport/mol/tl_mol_conservative_alg_mod.x90 +++ b/science/linear/source/algorithm/transport/mol/tl_mol_conservative_alg_mod.x90 @@ -15,7 +15,8 @@ module tl_mol_conservative_alg_mod LOG_LEVEL_INFO use mesh_mod, only: mesh_type use operator_mod, only: operator_type - use timer_mod, only: timer + use timing_mod, only: start_timing, stop_timing, & + tik, LPROF ! Algorithms and transport code use advective_and_flux_alg_mod, only: advective_and_flux_alg @@ -27,7 +28,7 @@ module tl_mol_conservative_alg_mod use runge_kutta_init_mod, only: get_rk_transport_weights use split_transport_utils_mod, only: get_num_split_steps, & get_splitting_direction - use transport_constants_mod, only: get_directional_im3_div + use transport_constants_mod, only: get_directional_im3_div_r_tran use transport_controller_mod, only: transport_controller_type use tl_transport_controller_mod, only: tl_transport_controller_type use transport_counter_mod, only: transport_counter_type @@ -42,7 +43,7 @@ module tl_mol_conservative_alg_mod ! Configuration use boundaries_config_mod, only: limited_area use base_mesh_config_mod, only: topology, topology_non_periodic - use io_config_mod, only: subroutine_timers + use linear_config_mod, only: transport_efficiency use transport_config_mod, only: runge_kutta_method, & dry_field_name, & operators, & @@ -79,6 +80,8 @@ module tl_mol_conservative_alg_mod integer(kind=i_def) :: stage, s, direction integer(kind=i_def) :: nstage, substep integer(kind=i_def) :: number_substeps + integer(kind=i_def) :: ls_nstage, ls_substep + integer(kind=i_def) :: ls_stage, ls_number_substeps integer(kind=i_def) :: step integer(kind=i_def) :: splitting real(kind=r_def) :: dt_mol_substep @@ -106,7 +109,9 @@ module tl_mol_conservative_alg_mod type(field_type), allocatable :: rk_field(:) real(kind=r_def), allocatable :: rk_weights(:,:) type(transport_metadata_type), pointer :: transport_metadata + type(transport_metadata_type), pointer :: ls_transport_metadata type(transport_counter_type), pointer :: transport_counter + type(transport_counter_type), pointer :: ls_transport_counter type(transport_controller_type), pointer :: transport_controller type(transport_controller_type), pointer :: ls_transport_controller type(transport_controller_type), pointer :: pert_transport_controller @@ -115,8 +120,9 @@ module tl_mol_conservative_alg_mod type(flux_precomputations_type), pointer :: flux_precomputations type(flux_precomputations_type), pointer :: ls_wind_flux_precomp type(flux_precomputations_type), pointer :: pert_wind_flux_precomp + integer(tik) :: id - if ( subroutine_timers ) call timer('tl_mol_conservative_alg') + if ( LPROF ) call start_timing( id, 'tl_transport.mol_conservative' ) ! ------------------------------------------------------------------------ ! ! Extract transport objects and initialise temporary fields @@ -126,11 +132,18 @@ module tl_mol_conservative_alg_mod transport_controller => tl_transport_controller%get_ls_wind_ls_rho_controller() ls_transport_controller => tl_transport_controller%get_ls_wind_pert_rho_controller() pert_transport_controller => tl_transport_controller%get_pert_wind_ls_rho_controller() + transport_metadata => pert_transport_controller%get_transport_metadata() + ls_transport_metadata => transport_controller%get_transport_metadata() + transport_counter => pert_transport_controller%get_transport_counter() + ls_transport_counter => transport_controller%get_transport_counter() + flux_precomputations => transport_controller%get_flux_precomputations() + ls_wind_flux_precomp => ls_transport_controller%get_flux_precomputations() pert_wind_flux_precomp => pert_transport_controller%get_flux_precomputations() + ls_wind_precomputations => ls_transport_controller%get_wind_precomputations() pert_wind_precomputations => pert_transport_controller%get_wind_precomputations() @@ -146,16 +159,27 @@ module tl_mol_conservative_alg_mod dt_mol_substep = ls_wind_precomputations%get_dt_mol_substep( & mesh%get_id(), direction, splitting, step & ) - div => get_directional_im3_div(mesh_id, direction) + div => get_directional_im3_div_r_tran(mesh_id, direction) call get_rk_transport_weights(nstage, rk_weights, runge_kutta_method) + + if (transport_efficiency) then + ls_number_substeps = 1 + ls_nstage = 1 + else + ls_number_substeps = number_substeps + ls_nstage = nstage + end if + allocate( rk_field(nstage) ) - allocate( stored_ls_field(number_substeps,nstage) ) + allocate( stored_ls_field(ls_number_substeps,ls_nstage) ) do stage = 1, nstage call rk_field(stage)%initialise(field%get_function_space()) - do substep = 1, number_substeps - call stored_ls_field(substep, stage)%initialise(field%get_function_space()) + end do + do ls_stage = 1, ls_nstage + do ls_substep = 1, ls_number_substeps + call stored_ls_field(ls_substep, ls_stage)%initialise(field%get_function_space()) end do end do call rhs_field%initialise( field%get_function_space() ) @@ -194,20 +218,23 @@ module tl_mol_conservative_alg_mod ! array for each substep and each RK stage to use in the perturbation ! ======================================================================== ! + if (transport_efficiency) then + call invoke( setval_X( stored_ls_field(1,1), ls_field_np1 ) ) + else ! ------------------------------------------------------------------------ ! ! Start of substepping loop ! ------------------------------------------------------------------------ ! - ls_substep_loop: do substep = 1, number_substeps + ls_substep_loop: do substep = 1, ls_number_substeps - final_substep = ( substep == number_substeps ) + final_substep = ( substep == ls_number_substeps ) ! Reset field_n ready for the this substep call ls_field_np1%copy_field_properties(ls_field_n) call invoke( setval_X(ls_field_n, ls_field_np1) ) - ls_stage_loop: do stage = 1, nstage + ls_stage_loop: do stage = 1, ls_nstage - final_rk_stage = ( stage == nstage ) + final_rk_stage = ( stage == ls_nstage ) ! Store values for use in the perturbation code. This is done before ! advecting so as to pick up the correct linearisation state @@ -248,7 +275,7 @@ module tl_mol_conservative_alg_mod call advective_and_flux_alg(flux_step, adv_inc, rhs_field, ls_field_n, & ls_advecting_wind, direction, & - transport_metadata, final_rk_stage, & + ls_transport_metadata, final_rk_stage, & dt_mol_substep, do_flux, do_advective) if ( do_flux ) then @@ -291,9 +318,11 @@ module tl_mol_conservative_alg_mod ! increment, and may be adjusted to enforce min value or in blending zone call end_of_conservative_step_alg( & ls_field_np1, ls_field, ls_sum_flux, flux_precomputations, & - transport_counter, transport_metadata & + ls_transport_counter, ls_transport_metadata & ) + end if + ! ======================================================================== ! ! Perturbation ! @@ -307,6 +336,12 @@ module tl_mol_conservative_alg_mod ! ------------------------------------------------------------------------ ! substep_loop: do substep = 1, number_substeps + if (transport_efficiency) then + ls_substep = 1 + else + ls_substep = substep + end if + final_substep = ( substep == number_substeps ) ! Reset field_n ready for the this substep @@ -315,6 +350,12 @@ module tl_mol_conservative_alg_mod stage_loop: do stage = 1, nstage + if (transport_efficiency) then + ls_stage = 1 + else + ls_stage = stage + end if + final_rk_stage = ( stage == nstage ) ! Compute the field for this stage: @@ -352,7 +393,7 @@ module tl_mol_conservative_alg_mod call tl_advective_and_flux_alg( & flux_step_ls_wind, flux_step_pert_wind, adv_inc, & rhs_field, advecting_wind, & - stored_ls_field(substep,stage), ls_advecting_wind, & + stored_ls_field(ls_substep,ls_stage), ls_advecting_wind, & direction, transport_metadata, final_rk_stage, & dt_mol_substep, do_flux, do_advective & ) @@ -411,7 +452,7 @@ module tl_mol_conservative_alg_mod if ( allocated(rk_weights) ) deallocate(rk_weights) if ( allocated(stored_ls_field) ) deallocate(stored_ls_field) - if ( subroutine_timers ) call timer('tl_mol_conservative_alg') + if ( LPROF ) call stop_timing( id, 'tl_transport.mol_conservative' ) end subroutine tl_mol_conservative_alg diff --git a/science/linear/source/driver/linear_driver_mod.f90 b/science/linear/source/driver/linear_driver_mod.f90 index 662faea60..c7ac56319 100644 --- a/science/linear/source/driver/linear_driver_mod.f90 +++ b/science/linear/source/driver/linear_driver_mod.f90 @@ -174,7 +174,7 @@ subroutine initialise( program_name, modeldb ) end if ! Instantiate the linearisation state - call linear_create_ls( modeldb, mesh ) + call linear_create_ls( modeldb, mesh, twod_mesh) ! Initialise the fields stored in the model_data if ( init_option == init_option_fd_start_dump ) then diff --git a/science/linear/source/driver/linear_model_data_mod.f90 b/science/linear/source/driver/linear_model_data_mod.f90 index 95befc39f..00c78d8ff 100644 --- a/science/linear/source/driver/linear_model_data_mod.f90 +++ b/science/linear/source/driver/linear_model_data_mod.f90 @@ -39,6 +39,7 @@ module linear_model_data_mod pert_option_file, & pert_option_zero, & ls_read_w2h + use linear_physics_config_mod, only : l_boundary_layer use linked_list_mod, only : linked_list_type use log_mod, only : log_event, & log_scratch_space, & @@ -71,23 +72,24 @@ module linear_model_data_mod !> @param[inout] modeldb The working data set for a model run !> @param[in] mesh The current 3d mesh !> - subroutine linear_create_ls( modeldb, mesh ) + subroutine linear_create_ls( modeldb, mesh, twod_mesh ) implicit none type( modeldb_type ), target, intent(inout) :: modeldb type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh select case( ls_option ) case( ls_option_analytic ) - call linear_create_ls_analytic( modeldb, mesh ) + call linear_create_ls_analytic( modeldb, mesh, twod_mesh ) case( ls_option_file ) - call linear_create_ls_file( modeldb, mesh ) + call linear_create_ls_file( modeldb, mesh, twod_mesh ) case default @@ -106,13 +108,14 @@ end subroutine linear_create_ls !> @param[inout] modeldb The working data set for a model run !> @param[in] mesh The current 3d mesh !> - subroutine linear_create_ls_analytic( modeldb, mesh ) + subroutine linear_create_ls_analytic( modeldb, mesh, twod_mesh ) implicit none type( modeldb_type ), target, intent(inout) :: modeldb type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh type( field_collection_type ), pointer :: depository type( field_collection_type ), pointer :: prognostics @@ -170,6 +173,10 @@ subroutine linear_create_ls_analytic( modeldb, mesh ) imr=imr ) end do + if (l_boundary_layer) & + call setup_field( ls_fields, depository, prognostics, "ls_land_fraction", W3, & + twod_mesh, checkpoint_restart_flag ) + end subroutine linear_create_ls_analytic !> @brief Create the fields in the ls fields field collection to be setup @@ -180,13 +187,14 @@ end subroutine linear_create_ls_analytic !> @param[inout] modeldb The working data set for a model run !> @param[in] mesh The current 3d mesh !> - subroutine linear_create_ls_file( modeldb, mesh ) + subroutine linear_create_ls_file( modeldb, mesh, twod_mesh ) implicit none type( modeldb_type ), target, intent(inout) :: modeldb type( mesh_type ), pointer, intent(in) :: mesh + type( mesh_type ), pointer, intent(in) :: twod_mesh type( field_collection_type ), pointer :: depository type( field_collection_type ), pointer :: prognostics @@ -243,6 +251,10 @@ subroutine linear_create_ls_file( modeldb, mesh ) call setup_field( ls_fields, depository, prognostics, "ls_theta", Wtheta, & mesh, checkpoint_restart_flag, time_axis=ls_time_axis ) + if (l_boundary_layer) & + call setup_field( ls_fields, depository, prognostics, "ls_land_fraction", W3, & + twod_mesh, checkpoint_restart_flag, time_axis=ls_time_axis ) + if ( ls_read_w2h ) then call setup_field( ls_fields, depository, prognostics, "ls_h_u", W2h, & mesh, checkpoint_restart_flag, time_axis=ls_time_axis ) @@ -454,4 +466,4 @@ subroutine linear_init_pert( mesh, twod_mesh, modeldb ) end subroutine linear_init_pert -end module linear_model_data_mod \ No newline at end of file +end module linear_model_data_mod diff --git a/science/linear/source/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod.F90 b/science/linear/source/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod.F90 index 87b4df84b..2763b7bd1 100644 --- a/science/linear/source/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod.F90 +++ b/science/linear/source/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod.F90 @@ -24,6 +24,10 @@ module tl_kinetic_energy_gradient_kernel_mod use fs_continuity_mod, only : W2 use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -161,7 +165,8 @@ subroutine tl_kinetic_energy_gradient_code(nlayers, & chi_2_e(df) = chi_2( loc ) chi_3_e(df) = chi_3( loc ) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi_1_e, chi_2_e, chi_3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) ! Linearisation state - values at dofs diff --git a/science/linear/source/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod.F90 b/science/linear/source/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod.F90 index d2c9c8193..fd814e936 100644 --- a/science/linear/source/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod.F90 +++ b/science/linear/source/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod.F90 @@ -19,6 +19,10 @@ module tl_project_eos_pressure_kernel_mod use fs_continuity_mod, only : W3, Wtheta use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -171,7 +175,8 @@ subroutine tl_project_eos_pressure_code(cell, nlayers, chi2_e(df) = chi2(map_chi(df) + k) chi3_e(df) = chi3(map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) ! Linearisation state diff --git a/science/linear/source/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod.F90 b/science/linear/source/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod.F90 index ad726c204..ddb5f7313 100644 --- a/science/linear/source/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod.F90 +++ b/science/linear/source/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod.F90 @@ -30,6 +30,10 @@ module tl_rhs_project_eos_kernel_mod use fs_continuity_mod, only : W3, Wtheta use kernel_mod, only : kernel_type + use base_mesh_config_mod, only: geometry, topology + use finite_element_config_mod, only: coord_system + use planet_config_mod, only: scaled_radius + implicit none private @@ -194,7 +198,8 @@ subroutine tl_rhs_project_eos_code(nlayers, chi2_e(df) = chi2(map_chi(df) + k) chi3_e(df) = chi3(map_chi(df) + k) end do - call coordinate_jacobian(ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & + call coordinate_jacobian(coord_system, geometry, topology, scaled_radius, & + ndf_chi, nqp_h, nqp_v, chi1_e, chi2_e, chi3_e, & ipanel, chi_basis, chi_diff_basis, jac, dj) ! Linearisation state diff --git a/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 new file mode 100644 index 000000000..9141565c8 --- /dev/null +++ b/science/linear/source/kernel/linear_physics/tl_bl_inc_kernel_mod.F90 @@ -0,0 +1,165 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief Computes u_inc, the change in TLM velocity due to TLM boundary layer processes. +module tl_bl_inc_kernel_mod + + use argument_mod, only : arg_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, & + GH_REAL, CELL_COLUMN, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + use reference_element_mod, only : N + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + + type, public, extends(kernel_type) :: tl_bl_inc_kernel_type + private + type(arg_type) :: meta_args(7) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! u_inc + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! u + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Auv + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! Buv_inv + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ew + arg_type(GH_FIELD, GH_INTEGER, GH_READ, ANY_DISCONTINUOUS_SPACE_1), & ! face_selector_ns + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ) & ! Blevs_m + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: tl_bl_inc_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: tl_bl_inc_code + +contains + +!> @brief Computes u_inc, the change in TLM velocity due to TLM boundary layer processes. +!> @details The algorithm uses coefficients Auv and Buv_inv computed in tl_compute_aubu_kernel_mod. +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] u_inc Change in TLM velocity due to TLM boundary layer processes +!! @param[in] u TLM velocity +!! @param[in] nlayers Number of layers +!! @param[in] Auv Coefficient for TLM boundary layer +!! @param[in] Buv_inv Inverse of coefficient for TLM boundary layer +!! @param[in] face_selector_ew 2D field indicating which W/E faces to loop over in this column +!! @param[in] face_selector_ns 2D field indicating which N/S faces to loop over in this column +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] ndf_w2 Number of degrees of freedom per cell for w2 space +!! @param[in] undf_w2 Number of unique degrees of freedom for w2 space +!! @param[in] map_w2 Dofmap for the cell at the base of the column for w2 +!! @param[in] ndf_w3_2d Number of DoFs for 2D W3 per cell +!! @param[in] undf_w3_2d Number of DoFs for this partition for 2D W3 +!! @param[in] map_w3_2d Map for 2D W3 +subroutine tl_bl_inc_code( nlayers, & + u_inc, & + u, & + Auv, & + Buv_inv, & + face_selector_ew, & + face_selector_ns, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3_2d, undf_w3_2d, map_w3_2d ) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + real(kind=r_def), dimension(undf_w2), intent(inout) :: u_inc + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + real(kind=r_def), dimension(undf_w2), intent(in) :: u + real(kind=r_def), dimension(undf_w2), intent(in) :: Auv + real(kind=r_def), dimension(undf_w2), intent(in) :: Buv_inv + integer(kind=i_def), intent(in) :: ndf_w3_2d, undf_w3_2d + integer(kind=i_def), dimension(ndf_w3_2d), intent(in) :: map_w3_2d + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ew + integer(kind=i_def), dimension(undf_w3_2d), intent(in) :: face_selector_ns + integer(kind=i_def), intent(in) :: Blevs_m + + ! Internal variables + integer(kind=i_def) :: df, k, j + real(kind=r_def) :: a0(1:BLevs_m) ! Coefficient + real(kind=r_def) :: a1(1:BLevs_m) ! Coefficient + real(kind=r_def) :: a2(1:BLevs_m) ! Coefficient + real(kind=r_def) :: u_rhs(1:BLevs_m) ! Local perturbation velocity variable + real(kind=r_def) :: u_out(1:BLevs_m) ! Local perturbation velocity variable + real(kind=r_def) :: factor_u(1:BLevs_m) + + ! Loop over horizontal W2 DoFs whilst minimising double counting. + ! (Looping over all dofs would mean that faces are visited twice – for the cells on both sides. + ! So here the loop is only for a specific selection of dofs.) + do j = 1, face_selector_ew(map_w3_2d(1)) + face_selector_ns(map_w3_2d(1)) + + df = j + if (j == 3 .and. face_selector_ns(map_w3_2d(1)) == 2 .and. face_selector_ew(map_w3_2d(1)) == 1) df = N + + a0 = 0.0_r_def + a1 = 0.0_r_def + a2 = 0.0_r_def + u_rhs = 0.0_r_def + u_out = 0.0_r_def + factor_u = 0.0_r_def + + ! Set up coeffs a0, a1, a2, u_rhs + do k = 1, BLevs_m + if (k == 1) then + a0(1) = 1.0_r_def + (Auv(map_w2(df) + 1) + Auv(map_w2(df) + 0)) / Buv_inv(map_w2(df) + 1) + a1(k) = -Auv(map_w2(df) + 1) / Buv_inv(map_w2(df) + 1) + u_rhs(1) = (Auv(map_w2(df) + 1) & + * (u(map_w2(df) + 1) - u(map_w2(df) + 0)) - Auv(map_w2(df) + 0) * u(map_w2(df) + 0)) / Buv_inv(map_w2(df) + 1) + else if (k > 1 .and. k < BLevs_m) then + a0(k) = 1.0_r_def + (Auv(map_w2(df) + k) + Auv(map_w2(df) + k - 1)) / Buv_inv(map_w2(df) + k) + a2(k) = -Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + a1(k) = -Auv(map_w2(df) + k) / Buv_inv(map_w2(df) + k) + u_rhs(k) = (Auv(map_w2(df) + k) & + * (u(map_w2(df) + k) - u(map_w2(df) + k - 1)) & + - Auv(map_w2(df) + k - 1) * (u(map_w2(df) + k - 1) - u(map_w2(df) + k - 2))) / Buv_inv(map_w2(df) + k) + else + a0(k) = 1.0_r_def + Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + a2(k) = -Auv(map_w2(df) + k - 1) / Buv_inv(map_w2(df) + k) + u_rhs(k) = -(Auv(map_w2(df) + k - 1) * (u(map_w2(df) + k - 1) - u(map_w2(df) + k - 2))) / Buv_inv(map_w2(df) + k) + end if + end do + + ! Transform to upper triangular form + do k = 1, BLevs_m + if (k == 1) then + a0(1) = 1.0_r_def / a0(1) + else + factor_u(k) = a2(k) * a0(k - 1) + a0(k) = 1.0_r_def / (a0(k) - factor_u(k) * a1(k - 1)) + u_rhs(k) = u_rhs(k) - factor_u(k) * u_rhs(k - 1) + end if + end do + + ! Solve for u_inc + u_out(BLevs_m) = a0(BLevs_m) * u_rhs(BLevs_m) + u_inc(map_w2(df) + BLevs_m - 1) = u_out(BLevs_m) + do k = BLevs_m - 1, 1, -1 + u_out(k) = a0(k) * (u_rhs(k) - a1(k) * u_out(k + 1)) + u_inc(map_w2(df) + k - 1) = u_out(k) + end do + + end do ! Loop over horizontal W2 DoFs + +end subroutine tl_bl_inc_code + +end module tl_bl_inc_kernel_mod diff --git a/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 new file mode 100644 index 000000000..1f16f4b81 --- /dev/null +++ b/science/linear/source/kernel/linear_physics/tl_compute_aubu_kernel_mod.F90 @@ -0,0 +1,117 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief Computes coefficients Auv and Buv_inv used in the TLM boundary layer scheme for momentum. +module tl_compute_aubu_kernel_mod + + use argument_mod, only : arg_type, func_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, GH_READWRITE, & + GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3 + use kernel_mod, only : kernel_type + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + type, public, extends(kernel_type) :: tl_compute_aubu_kernel_type + private + type(arg_type) :: meta_args(8) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! Auv + arg_type(GH_FIELD, GH_REAL, GH_INC, W2), & ! Buv_inv + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! Q + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! E + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! height_w2 + arg_type(GH_FIELD, GH_REAL, GH_READ, W2), & ! w2_rmultiplicity + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! dt + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ) & ! Blevs_m + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: tl_compute_aubu_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: tl_compute_aubu_code + +contains + +!> @brief Computes coefficients Auv and Buv_inv used in the TLM boundary layer scheme for momentum. +!> @details Auv and Buv_inv are derived from coefficients Q and E which are computed in tl_compute_qe_kernel_mod. +!> The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] Auv Coefficient for TLM boundary layer +!! @param[in,out] Buv_inv Inverse of coefficient for TLM boundary layer +!! @param[in] Q Coefficient for TLM boundary layer +!! @param[in] E Coefficient for TLM boundary layer +!! @param[in] height_w2 Height of w2 space levels above the surface +!! @param[in] w2_rmultiplicity Reciprocal of multiplicity for W2 +!! @param[in] dt TLM time step +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] ndf_w2 Number of degrees of freedom per cell for w2 space +!! @param[in] undf_w2 Number of unique degrees of freedom for w2 space +!! @param[in] map_w2 Dofmap for the cell at the base of the column for w2 +!! @param[in] ndf_w3 Number of degrees of freedom per cell for w3 space +!! @param[in] undf_w3 Number of unique degrees of freedom for w3 space +!! @param[in] map_w3 Dofmap for the cell at column base for w3 +subroutine tl_compute_aubu_code( nlayers, & + Auv, & + Buv_inv, & + Q, & + E, & + height_w2, & + w2_rmultiplicity, & + dt, & + Blevs_m, & + ndf_w2, undf_w2, map_w2, & + ndf_w3, undf_w3, map_w3) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + integer(kind=i_def), intent(in) :: undf_w2, ndf_w2 + integer(kind=i_def), dimension(ndf_w2), intent(in) :: map_w2 + real(kind=r_def), dimension(undf_w2), intent(in) :: w2_rmultiplicity + real(kind=r_def), dimension(undf_w2), intent(inout) :: Auv !(0:BLevs_m) + real(kind=r_def), dimension(undf_w2), intent(inout) :: Buv_inv ! Use inverse of Buv as this is what is averaged + real(kind=r_def), dimension(undf_w3), intent(in) :: Q ! (0:BLevs_m) + real(kind=r_def), dimension(undf_w3), intent(in) :: E ! (BLevs_m) + real(kind=r_def), dimension(undf_w2), intent(in) :: height_w2 + real(kind=r_def), intent(in) :: dt + integer(kind=i_def), intent(in) :: Blevs_m + + ! Internal variables + integer(kind=i_def) :: df, df3, k + + df3 = 1 + + do df = 1, 4 + do k = 0, BLevs_m + if (k == 0) then + Auv(map_w2(df) + k) = w2_rmultiplicity(map_w2(df)) * Q(map_w3(df3)) + else ! 1 <= k <= BLevs_m + Auv(map_w2(df) + k) = & + w2_rmultiplicity(map_w2(df) + k) * Q(map_w3(df3) + k) / (height_w2(map_w2(df) + k) - height_w2(map_w2(df) + k - 1)) + Buv_inv(map_w2(df) + k) = ( w2_rmultiplicity(map_w2(df) + k) * E(map_w3(df3) + k) ) / dt + end if + end do ! k = 0, BLevs_m + end do ! df = 1, 4 + +end subroutine tl_compute_aubu_code + +end module tl_compute_aubu_kernel_mod diff --git a/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 new file mode 100644 index 000000000..89c6a7710 --- /dev/null +++ b/science/linear/source/kernel/linear_physics/tl_compute_qe_kernel_mod.F90 @@ -0,0 +1,179 @@ +!----------------------------------------------------------------------------- +! (C) Crown copyright 2026 Met Office. All rights reserved. +! The file LICENCE, distributed with this code, contains details of the terms +! under which the code may be used. +!----------------------------------------------------------------------------- +!> @brief Computes coefficients Q and E used in the TLM boundary layer scheme for momentum. +module tl_compute_qe_kernel_mod + + use argument_mod, only : arg_type, func_type, & + GH_FIELD, GH_OPERATOR, & + GH_SCALAR, GH_INTEGER, & + GH_READ, GH_INC, GH_READWRITE, & + GH_REAL, CELL_COLUMN, GH_BASIS, GH_EVALUATOR, & + ANY_DISCONTINUOUS_SPACE_1 + use constants_mod, only : r_def, i_def, r_um + use fs_continuity_mod, only : W1, W2, W3, Wtheta + use kernel_mod, only : kernel_type + + implicit none + + private + + !--------------------------------------------------------------------------- + ! Public types + !--------------------------------------------------------------------------- + type, public, extends(kernel_type) :: tl_compute_qe_kernel_type + private + type(arg_type) :: meta_args(14) = (/ & + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! Q + arg_type(GH_FIELD, GH_REAL, GH_READWRITE, W3), & ! E + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! ls_rho + arg_type(GH_FIELD, GH_REAL, GH_READ, W3), & ! height_w3 + arg_type(GH_FIELD, GH_REAL, GH_READ, Wtheta), & ! height_wth + arg_type(GH_FIELD, GH_REAL, GH_READ, ANY_DISCONTINUOUS_SPACE_1 ), & ! ls_land_fraction + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! log_layer + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! Blevs_m + arg_type(GH_SCALAR, GH_INTEGER, GH_READ ), & ! e_folding_levs_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_land_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! u_sea_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_land_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ), & ! z_sea_m + arg_type(GH_SCALAR, GH_REAL, GH_READ ) & ! L_0_m + /) + integer :: operates_on = CELL_COLUMN + contains + procedure, nopass :: tl_compute_qe_code + end type + + !--------------------------------------------------------------------------- + ! Contained functions/subroutines + !--------------------------------------------------------------------------- + public :: tl_compute_qe_code + +contains + +!> @brief Computes coefficients Q and E used in the TLM boundary layer scheme for momentum. +!> @details The TLM BL scheme is described in Var Scientific Documentation Paper 55, +!> https://wwwspice/~frva/VAR/view/var-2025.03.0/doc/VSDP55_1A.pdf +!! @param[in] nlayers Number of layers +!! @param[in,out] Q Coefficient for TLM boundary layer +!! @param[in,out] E Coefficient for TLM boundary layer +!! @param[in] ls_rho Linearisation state for density +!! @param[in] height_w3 Height of w3 space levels above the surface +!! @param[in] height_wth Height of wth space levels above surface +!! @param[in] ls_land_fraction Land area fraction +!! @param[in] log_layer Number of levels in log layer +!! @param[in] Blevs_m Number of levels in momentum boundary layer +!! @param[in] e_folding_levs_m e-folding level in exchange coefficient for momemtum +!! @param[in] z_land_m Effective roughness length for momemtum over land +!! @param[in] z_sea_m Effective roughness length for momemtum over sea +!! @param[in] u_land_m Friction velocity for momemtum over land +!! @param[in] u_sea_m Friction velocity for momemtum over sea +!! @param[in] L_0_m Mixing length for momemtum +!! @param[in] ndf_w3 Number of degrees of freedom per cell for w3 space +!! @param[in] undf_w3 Number of unique degrees of freedom for w3 space +!! @param[in] map_w3 Dofmap for the cell at column base for w3 +!! @param[in] ndf_wtheta Number of degrees of freedom per cell for wtheta space +!! @param[in] undf_wtheta Number of unique degrees of freedom for wtheta space +!! @param[in] map_wtheta Dofmap for the cell at the base of the column for wtheta +!! @param[in] ndf_2d Number of degrees of freedom per cell for 2D field +!! @param[in] undf_2d Number of unique degrees of freedom for 2D field +!! @param[in] map_2d Dofmap for 2D field +subroutine tl_compute_qe_code( nlayers, & + Q, & + E, & + ls_rho, & + height_w3, & + height_wth, & + ls_land_fraction, & + log_layer, & + Blevs_m, & + e_folding_levs_m, & + u_land_m, & + u_sea_m, & + z_land_m, & + z_sea_m, & + L_0_m, & + ndf_w3, undf_w3, map_w3, & + ndf_wtheta, undf_wtheta, map_wtheta, & + ndf_2d, undf_2d, map_2d ) + + implicit none + + ! Arguments + integer(kind=i_def), intent(in) :: nlayers + integer(kind=i_def), intent(in) :: undf_w3, ndf_w3 + integer(kind=i_def), dimension(ndf_w3), intent(in) :: map_w3 + integer(kind=i_def), intent(in) :: undf_wtheta, ndf_wtheta + integer(kind=i_def), dimension(ndf_wtheta), intent(in) :: map_wtheta + integer(kind=i_def), intent(in) :: undf_2d, ndf_2d + integer(kind=i_def), dimension(ndf_2d), intent(in) :: map_2d + real(kind=r_def), dimension(undf_w3), intent(inout) :: Q ! (0:BLevs_m) + real(kind=r_def), dimension(undf_w3), intent(inout) :: E ! (BLevs_m) + real(kind=r_def), dimension(undf_w3), intent(in) :: ls_rho + real(kind=r_def), dimension(undf_w3), intent(in) :: height_w3 + real(kind=r_def), dimension(undf_wtheta), intent(in) :: height_wth + real(kind=r_def), dimension(undf_2d), intent(in) :: ls_land_fraction + integer(kind=i_def), intent(in) :: log_layer,Blevs_m,e_folding_levs_m + real(kind=r_def), intent(in) :: u_land_m, u_sea_m, z_land_m, z_sea_m, L_0_m + + ! Internal variables + integer(kind=i_def) :: df, k + real(kind=r_def) :: roughness_length_m + real(kind=r_def), parameter :: Von_Karman = 0.4_r_def + real(kind=r_def) :: L_diff_m(1:BLevs_m) + real(kind=r_def) :: u1 + real(kind=r_def) :: num + real(kind=r_def) :: denom + + df = 1 ! map_w3 only has range 1:1, map_wtheta has range 1:2 with 1 being lower face of cell + roughness_length_m = z_land_m * ls_land_fraction(map_2d(df)) + z_sea_m * (1.0_r_def - ls_land_fraction(map_2d(df))) + + ! Define the mixing length, L_diff + ! L_diff is on centre of horizontal faces - for convenience indexed by centre of cell above. + ! Vertical numbering (k index) matches that in old Var schemePF_bdy_lyr.f90 (see link above), + ! in which centre of lowest cell is rho level 1 (allowing for the fact that the PF model is for New Dynamics, + ! which has an extra rho level which means that W3 k=0 in LFRic is equivalent to rho levels k=1 in VAR). + ! L_diff_m(k) defined for 1 <= k <= BLevs_m. + do k = 1, BLevs_m + if (k <= Log_layer) then + ! num and denom to take log of + num = height_w3(map_w3(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m + denom = height_w3(map_w3(df) + k - 1) - height_wth(map_wtheta(df)) + roughness_length_m + ! num and denom of final expression + denom = log(num / denom) + Von_Karman * (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) / L_0_m + num = (height_w3(map_w3(df) + k) - height_w3(map_w3(df) + k - 1)) + else + num = height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m + denom = 1.0_r_def + (height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df)) + roughness_length_m) / L_0_m + end if + L_diff_m(k) = Von_Karman * num / denom + end do + + ! Define Q and E + ! E is on cell centres + ! Q is on centre of horizontal faces - for convenience indexed by centre of cell above + ! Q(k) defined for 0 <= k <= BLevs_m + ! E(k) defined for 1 <= k <= BLevs_m + u1 = u_land_m * ls_land_fraction(map_2d(df)) + u_sea_m * (1.0_r_def - ls_land_fraction(map_2d(df))) + do k = 0, BLevs_m + if (k == 0) then + ! num and denom to take log of + num = height_w3(map_w3(df) + 0) - height_wth(map_wtheta(df) + 0) + roughness_length_m + denom = roughness_length_m + ! num and denom of final expression + denom = log(num / denom) + num = Von_Karman * u1 + Q(map_w3(df) + k) = num / denom + else ! i.e., k >= 1 + num = height_wth(map_wtheta(df)) - height_wth(map_wtheta(df) + k) + denom = height_wth(map_wtheta(df) + e_folding_levs_m) - height_wth(map_wtheta(df)) + Q(map_w3(df) + k) = L_diff_m(k) * u1 * exp(num / denom) + E(map_w3(df) + k) = ls_rho(map_w3(df) + k - 1) * (height_wth(map_wtheta(df) + k) - height_wth(map_wtheta(df) + k - 1)) + end if + end do + +end subroutine tl_compute_qe_code + +end module tl_compute_qe_kernel_mod diff --git a/science/linear/source/kernel/transport/common/tl_vorticity_advection_kernel_mod.F90 b/science/linear/source/kernel/transport/common/tl_vorticity_advection_kernel_mod.F90 index a2c4c1078..009dc5998 100644 --- a/science/linear/source/kernel/transport/common/tl_vorticity_advection_kernel_mod.F90 +++ b/science/linear/source/kernel/transport/common/tl_vorticity_advection_kernel_mod.F90 @@ -23,6 +23,10 @@ module tl_vorticity_advection_kernel_mod use fs_continuity_mod, only: W1, W2 use cross_product_mod, only: cross_product +use base_mesh_config_mod, only: geometry, topology +use finite_element_config_mod, only: coord_system +use planet_config_mod, only: scaled_radius + implicit none !------------------------------------------------------------------------------- @@ -183,8 +187,10 @@ subroutine tl_vorticity_advection_code(nlayers, & do qp1 = 1, nqp_h ! Constants - call pointwise_coordinate_jacobian(ndf_chi, chi_1_e, chi_2_e, chi_3_e, & - ipanel, chi_basis(:,:,qp1,qp2), & + call pointwise_coordinate_jacobian(coord_system, geometry, & + topology, scaled_radius, & + ndf_chi, chi_1_e, chi_2_e, chi_3_e, & + ipanel, chi_basis(:,:,qp1,qp2), & chi_diff_basis(:,:,qp1,qp2), jac, dj) jac_inv = pointwise_coordinate_jacobian_inverse(jac, dj) jac = matmul(jac_inv,transpose(jac_inv)) diff --git a/science/linear/unit-test/kernel/core_dynamics/initial_theta_ref_kernel_mod_test.pf b/science/linear/unit-test/kernel/core_dynamics/initial_theta_ref_kernel_mod_test.pf index c3b98a7b0..45a8e1ae3 100644 --- a/science/linear/unit-test/kernel/core_dynamics/initial_theta_ref_kernel_mod_test.pf +++ b/science/linear/unit-test/kernel/core_dynamics/initial_theta_ref_kernel_mod_test.pf @@ -112,7 +112,7 @@ contains profile_data=profile_data, & profile_heights=profile_heights ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/science/linear/unit-test/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod_test.pf b/science/linear/unit-test/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod_test.pf index 9a44a87ab..7fbc2b3a6 100644 --- a/science/linear/unit-test/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod_test.pf +++ b/science/linear/unit-test/kernel/core_dynamics/tl_kinetic_energy_gradient_kernel_mod_test.pf @@ -7,7 +7,7 @@ !>@brief Test the tangent linear gradient of the kinetic energy computation module tl_kinetic_energy_gradient_kernel_mod_test - use constants_mod, only : i_def, r_def + use constants_mod, only : i_def, r_def, imdi use get_unit_test_m3x3_q3x3x3_sizes_mod, only : get_w0_m3x3_q3x3x3_size, & get_w2_m3x3_q3x3x3_size, & @@ -91,7 +91,7 @@ contains horizontal_transport_predictor=.false., & vector_invariant=.false.) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) end subroutine setUp diff --git a/science/linear/unit-test/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod_test.pf b/science/linear/unit-test/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod_test.pf index e739d0615..a34f52bc8 100644 --- a/science/linear/unit-test/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod_test.pf +++ b/science/linear/unit-test/kernel/core_dynamics/tl_project_eos_pressure_kernel_mod_test.pf @@ -86,7 +86,7 @@ contains profile_heights=profile_heights ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) call feign_planet_config( gravity=10.0_r_def, & omega=8.0E-5_r_def, & diff --git a/science/linear/unit-test/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod_test.pf b/science/linear/unit-test/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod_test.pf index c80f072b3..f8cae079c 100644 --- a/science/linear/unit-test/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod_test.pf +++ b/science/linear/unit-test/kernel/core_dynamics/tl_rhs_project_eos_kernel_mod_test.pf @@ -91,7 +91,7 @@ contains profile_data=profile_data, & profile_heights=profile_heights ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine setUp diff --git a/science/linear/unit-test/kernel/core_dynamics/tl_sample_eos_pressure_kernel_mod_test.pf b/science/linear/unit-test/kernel/core_dynamics/tl_sample_eos_pressure_kernel_mod_test.pf index e1dc1c860..9617cb413 100644 --- a/science/linear/unit-test/kernel/core_dynamics/tl_sample_eos_pressure_kernel_mod_test.pf +++ b/science/linear/unit-test/kernel/core_dynamics/tl_sample_eos_pressure_kernel_mod_test.pf @@ -91,7 +91,7 @@ contains p_zero=100000.0_r_def, & scaling_factor=1.0_r_def ) - call init_chi_transforms() + call init_chi_transforms(geometry_planar, topology_fully_periodic) end subroutine set_up diff --git a/science/linear/unit-test/kernel/transport/common/tl_vorticity_advection_kernel_mod_test.pf b/science/linear/unit-test/kernel/transport/common/tl_vorticity_advection_kernel_mod_test.pf index 9dea4bf34..32c184999 100644 --- a/science/linear/unit-test/kernel/transport/common/tl_vorticity_advection_kernel_mod_test.pf +++ b/science/linear/unit-test/kernel/transport/common/tl_vorticity_advection_kernel_mod_test.pf @@ -7,7 +7,7 @@ !>@brief Test the tangent linear of the vorticity advection. module tl_vorticity_advection_kernel_mod_test - use constants_mod, only: i_def, r_def + use constants_mod, only: i_def, r_def, imdi use funit use finite_element_config_mod, & @@ -134,7 +134,7 @@ contains rehabilitate=.true., & vorticity_in_w1=.false. ) - call init_chi_transforms() + call init_chi_transforms(imdi, imdi) ! Get infrastructure support data !===================================== diff --git a/science/physics_schemes/source/boundary_layer/bdy_expl2.F90 b/science/physics_schemes/source/boundary_layer/bdy_expl2.F90 index af0136c06..557125c8a 100644 --- a/science/physics_schemes/source/boundary_layer/bdy_expl2.F90 +++ b/science/physics_schemes/source/boundary_layer/bdy_expl2.F90 @@ -46,7 +46,7 @@ subroutine bdy_expl2 ( & ! in cloud/moisture data : cf_bulk,q,qcf,qcl,t,qw,tl, & ! in everything not covered so far : - rad_hr,micro_tends,fb_surf,u_s,pstar,tstar,h_blend_orog, & + rad_hr,micro_tends,fb_surf,u_s,pstar,tstar, & zh_prev,zhpar,z_lcl,ho2r2_orog,sd_orog,wtrac_as, & ! 2 in 3 INOUT for Smagorinsky delta_smag, max_diff, rneutml_sq, visc_m, visc_h, & @@ -77,11 +77,11 @@ subroutine bdy_expl2 ( & off, max_t_grad, a_grad_adj, sg_orog_mixing, l_use_surf_in_ri, & h_scale, t_drain, idyndiag, DynDiag_ZL, l_noice_in_turb, & DynDiag_ZL_corrn, DynDiag_ZL_CuOnly, DynDiag_Ribased, & - RiCrit_sharp, zhloc_depth_fac, non_local_bl, on, l_full_lambdas, & + RiCrit_sharp, zhloc_depth_fac, non_local_bl, on, & nl_bl_levels, local_fa, free_trop_layers, to_sharp_across_1km, & sbl_op, equilibrium_sbl, one_third, two_thirds, blending_option, & blend_except_cu, blend_cth_shcu_only, sg_shear, sg_shear_enh_lambda, & - max_tke, var_diags_opt, original_vars, split_tke_and_inv, tke_diag_fac, & + max_tke, tke_diag_fac, & i_interp_local, i_interp_local_gradients, i_interp_local_cf_dbdz, & shallow_cu_maxtop, sc_cftol, near_neut_z_on_l, zero, one, one_half use cloud_inputs_mod, only: i_rhcpt, forced_cu, i_cld_vn, i_pc2_init_method, & @@ -257,9 +257,6 @@ subroutine bdy_expl2 ( & ! in Surface pressure (Pascals). tstar(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end), & ! in Surface temperature (K). - h_blend_orog(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end), & - ! in Blending height used as part - ! of effective roughness scheme zh_prev(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end), & ! in boundary layer height from ! previous timestep @@ -808,12 +805,9 @@ subroutine bdy_expl2 ( & real(kind=r_bl), parameter :: max_abs_obkhov = 1.0e6_r_bl ! Maximum permitted magnitude of the Obukhov ! length (m). -real(kind=r_bl), parameter :: small_sh = 0.01_r_bl - ! Minimum value of sh used in - ! original_vars variance diagnostics real(kind=r_bl), parameter :: small_tke = 1.0e-6_r_bl ! Minimum required value of TKE before - ! split_tke_and_inv variance diagnostics are calculated + ! variance diagnostics are calculated real(kind=r_bl), parameter :: max_ri = 0.01_r_bl*sqrt(huge(one)) ! Maximum (absolute) Richardson number which ensures that ! the stability functions (~ri^2) remain real-valued at @@ -957,11 +951,10 @@ subroutine bdy_expl2 ( & ! heterogeneous land surface this is poorly defined and we can't use Rib ! from the surface scheme as vertically averaging Ri is numerically ! unstable. So, over land, only the average temperature gradient is used -if ( .not. l_use_surf_in_ri .and. (var_diags_opt > original_vars .or. & - i_interp_local == i_interp_local_cf_dbdz ) ) then +if (.not. l_use_surf_in_ri) then ! if not using surface variables in Ri (l_use_surf_in_ri=false) we - ! extrapolate dbdz itself from level 2, but the sl and qw gradients are - ! used in the newer variance calculations and with i_interp_local_cf_dbdz + ! extrapolate dbdz itself from level 2, with the sl and qw gradients being + ! used in the variance calculations and with i_interp_local_cf_dbdz ! so extrapolate them here !$OMP do SCHEDULE(STATIC) do j = pdims%j_start, pdims%j_end @@ -2002,11 +1995,10 @@ subroutine bdy_expl2 ( & !----------------------------------------------------------------------- call ex_coef ( & ! in levels/logicals - bl_levels,k_log_layr,nSCMDpkgs,L_SCMDiags,BL_diag, & + bl_levels,k_log_layr,BL_diag, & ! in fields - sigma_h,flandg,dbdz,dvdzm,ri,rho_wet_tq,z_uv,z_tq,z0m_eff_gb, & - h_blend_orog,zhpar,ntpar,ntml_nl,ntdsc,nbdsc,u_p,v_p,u_s,fb_surf, & - qw,tl,l_shallow_cth,rmlmax2, rneutml_sq, delta_smag, & + sigma_h,flandg,dvdzm,ri,rho_wet_tq,z_uv,z_tq,z0m_eff_gb,zhpar,ntpar, & + ntml_nl,ntdsc,nbdsc,l_shallow_cth,rmlmax2,rneutml_sq,delta_smag, & ! in/out fields cumulus,weight_1dbl, & ! out fields @@ -2067,27 +2059,6 @@ subroutine bdy_expl2 ( & ! Include mixing length, ELH, in RHOKH. ! Code moved from EX_COEF to avoid interpolation !------------------------------------------------------------ - if ( k >= ntml_local(i,j)+2 .and. l_full_lambdas .and. & - local_fa == to_sharp_across_1km ) then - ! Assuming only LOCAL_FA = "to_sharp_across_1km" option - ! will have L_FULL_LAMBDAS. - ! If other LOCAL_FA options are coded here then - ! changes must be included in section 2.1 of ex_coef - if (l_rp2) then - lambdah = max ( lambda_min , & - par_mezcla_rp(rp_idx)*zh_local(i,j) ) - else - lambdah = max ( lambda_min , 0.15_r_bl*zh_local(i,j) ) - end if - z_scale = 1000.0_r_bl - weight1 = one_half*( one - & - tanh(3.0_r_bl*((z_uv(i,j,k)/z_scale )-one) ) ) - lambdah = lambdah * weight1 & - + lambda_min*( one - weight1) - ! no need to do log profile correction as klog_layr eq 2 - vkz = vkman * ( z_uv(i,j,k) + z0m_eff_gb(i,j) ) - elh_rho(i,j,k) = vkz / (one + vkz/lambdah ) - end if ! Reinstate UKV drainage flow bug here, where lambdah was not ! enhanced as intended (and as was done in ex_coef)! if (sg_orog_mixing == sg_shear_enh_lambda) then @@ -2097,7 +2068,7 @@ subroutine bdy_expl2 ( & else lambdah = max ( lambda_min , 0.15_r_bl*zh_local(i,j) ) end if - if (k >= ntml_local(i,j)+2 .and. .not. l_full_lambdas) then + if (k >= ntml_local(i,j)+2) then lambdah = lambda_min end if if (k <= k_log_layr) then @@ -2226,65 +2197,37 @@ subroutine bdy_expl2 ( & ! function of ustar, wstar) but is currently just set to zero if (BL_diag%l_tke) then - if (var_diags_opt == original_vars) then - ! BL_diag%tke currently contains (the reciprocal of) the non-local - ! (SML and DSC) mixed layer timescale, calculated in excf_nl - -!$OMP PARALLEL do SCHEDULE(STATIC) DEFAULT(none) & -!$OMP SHARED(BL_diag, rho_wet_tq, rhokm, dbdz, bl_levels, pdims) & -!$OMP private(i, j, k, recip_time_sbl, recip_time_cbl) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - - ! stable timescale - recip_time_sbl = sqrt( max(dbdz(i,j,k),1.0e-5_r_bl) )/0.7_r_bl - recip_time_cbl = BL_diag%tke(i,j,k) - - ! TKE diagnostic - taking 5 m2/s2 as a suitable maximum - BL_diag%tke(i,j,k)= min( max_tke, & - ( rhokm(i,j,k) / rho_wet_tq(i,j,k-1) )*( & - recip_time_cbl + recip_time_sbl ) ) - - end do - end do - end do -!$OMP end PARALLEL do - - else if (var_diags_opt == split_tke_and_inv) then - ! Combine the, separately calculated, local and non-local TKE diagnostics + ! Combine the, separately calculated, local and non-local TKE diagnostics !$OMP PARALLEL do SCHEDULE(STATIC) DEFAULT(none) & !$OMP SHARED(BL_diag, tke_nl, tke_loc, rho_wet_tq, weight_1dbl, & !$OMP tke_diag_fac, bl_levels, pdims) & !$OMP private(i, j, k) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end + do k = 2, bl_levels + do j = pdims%j_start, pdims%j_end + do i = pdims%i_start, pdims%i_end - ! TKE diagnostic - ! Currently tke_nl is strictly rho*sigma_w^2 while tke_loc is TKE - ! Assume isotropic turb so TKE_nl = 3/2 sigma_w^2 - tke_nl(i,j,k) = weight_1dbl(i,j,k) * 1.5_r_bl * & - tke_nl(i,j,k)/rho_wet_tq(i,j,k-1) - BL_diag%tke(i,j,k) = max( tke_loc(i,j,k), tke_nl(i,j,k) ) + ! TKE diagnostic + ! Currently tke_nl is strictly rho*sigma_w^2 while tke_loc is TKE + ! Assume isotropic turb so TKE_nl = 3/2 sigma_w^2 + tke_nl(i,j,k) = weight_1dbl(i,j,k) * 1.5_r_bl * & + tke_nl(i,j,k)/rho_wet_tq(i,j,k-1) + BL_diag%tke(i,j,k) = max( tke_loc(i,j,k), tke_nl(i,j,k) ) - ! Multiply by tuning factor - BL_diag%tke(i,j,k) = tke_diag_fac * BL_diag%tke(i,j,k) + ! Multiply by tuning factor + BL_diag%tke(i,j,k) = tke_diag_fac * BL_diag%tke(i,j,k) - ! Keep TKE below a sensible max value of max_tke - BL_diag%tke(i,j,k) = min( max_tke, BL_diag%tke(i,j,k) ) - ! Applying this limit can occasionally cause the length-scale - ! Km / sqrt(w_var) to become unrealistically large, since no - ! equivalent limiting is done on Km. + ! Keep TKE below a sensible max value of max_tke + BL_diag%tke(i,j,k) = min( max_tke, BL_diag%tke(i,j,k) ) + ! Applying this limit can occasionally cause the length-scale + ! Km / sqrt(w_var) to become unrealistically large, since no + ! equivalent limiting is done on Km. - end do end do end do + end do !$OMP end PARALLEL do - end if ! var_diags_opt - if ( i_bm_ez_opt == i_bm_ez_entpar ) then ! Calculate mixing-length to pass to bimodal cloud scheme, ! using Km and TKE. @@ -2362,7 +2305,7 @@ subroutine bdy_expl2 ( & ! to the microphysics turbulence call !$OMP PARALLEL DEFAULT(none) private(k,j,i) & -!$OMP SHARED(tdims, bl_levels,pdims,BL_diag,bl_w_var,var_diags_opt) +!$OMP SHARED(tdims, bl_levels,pdims,BL_diag,bl_w_var) !$OMP do SCHEDULE(STATIC) do k = 2, tdims%k_end+1 @@ -2374,73 +2317,41 @@ subroutine bdy_expl2 ( & end do !$OMP end do - if (var_diags_opt == original_vars) then - ! Original version: w_var = TKE + ! w_var = 2/3 TKE !$OMP do SCHEDULE(STATIC) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - if (BL_diag%tke(i,j,k) > 1.0e-12_r_bl) then - bl_w_var(i,j,k) = BL_diag%tke(i,j,k) - end if - end do - end do - end do -!$OMP end do - else if (var_diags_opt == split_tke_and_inv) then - ! Improved version: w_var = 2/3 TKE -!$OMP do SCHEDULE(STATIC) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - if (BL_diag%tke(i,j,k) > 1.0e-12_r_bl) then - bl_w_var(i,j,k) = two_thirds * BL_diag%tke(i,j,k) - end if - end do + do k = 2, bl_levels + do j = pdims%j_start, pdims%j_end + do i = pdims%i_start, pdims%i_end + if (BL_diag%tke(i,j,k) > 1.0e-12_r_bl) then + bl_w_var(i,j,k) = two_thirds * BL_diag%tke(i,j,k) + end if end do end do + end do !$OMP end do - end if ! test on var_diags_opt !$OMP end PARALLEL end if ! l_subgrid_qcl_mp .or. l_wvar_for_conv - if (var_diags_opt == original_vars) then - ! at this point, BL_diag%tke really contains 1.5*sigma_w^2. To make it look - ! a bit more like TKE near the surface, we will keep it constant below - ! the max of rhokm_surf -!$OMP PARALLEL do SCHEDULE(STATIC) DEFAULT(none) & -!$OMP SHARED( pdims, rhokmz, BL_diag ) private(i, j, k, kmax ) - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - kmax = maxloc(rhokmz(i,j,:), dim=1) - do k = 2, kmax - BL_diag%tke(i,j,k) = BL_diag%tke(i,j,kmax) - end do - end do - end do -!$OMP end PARALLEL do - else if (var_diags_opt == split_tke_and_inv) then - ! at this point, tke_nl really contained 1.5*sigma_w^2. To make it look - ! a bit more like TKE near the surface, we will keep it constant below - ! the max of rhokm_surf (here we find the first local maximum in case there - ! is a larger rhokmz in a resolved inversion + ! At this point, tke_nl really contained 1.5*sigma_w^2. To make it look + ! a bit more like TKE near the surface, we will keep it constant below + ! the max of rhokm_surf (here we find the first local maximum in case there + ! is a larger rhokmz in a resolved inversion !$OMP PARALLEL do SCHEDULE(STATIC) DEFAULT(none) & !$OMP SHARED( pdims, bl_levels, rhokmz, BL_diag, tke_loc, tke_nl ) & !$OMP private(i, j, k, kp) - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - kp=2 - do while ( rhokmz(i,j,kp+1) > rhokmz(i,j,kp) .and. kp < bl_levels ) - kp = kp +1 - end do - do k = 2, kp-1 - BL_diag%tke(i,j,k) = max( tke_loc(i,j,k), tke_nl(i,j,kp) ) - end do + do j = pdims%j_start, pdims%j_end + do i = pdims%i_start, pdims%i_end + kp=2 + do while ( rhokmz(i,j,kp+1) > rhokmz(i,j,kp) .and. kp < bl_levels ) + kp = kp +1 + end do + do k = 2, kp-1 + BL_diag%tke(i,j,k) = max( tke_loc(i,j,k), tke_nl(i,j,kp) ) end do end do + end do !$OMP end PARALLEL do - end if ! test on var_diags_opt end if ! BL_diag%L_tke @@ -2915,14 +2826,6 @@ subroutine bdy_expl2 ( & ! slvar,qwvar,slqw are on theta-level K ! tke is on theta-level K-1 ! exner is on theta-level K-1 - - ! For var_diags_opt = original_vars we use the following variables: - ! dsldzm is on theta-level K-1 - ! dqwdzm is on theta-level K-1 - ! elm is on theta-level K-1 - ! rhokh is on rho-level K - - ! For var_diags_opt = split_tke_and_inv ! dsldz is on rho-level K ! dqwdz is on rho-level K ! ftl is on rho-level k @@ -2943,85 +2846,47 @@ subroutine bdy_expl2 ( & call qsat_wat(qsw_arr,tl(:,j,k-1),p_theta_levels(:,j,k-1),tdims%i_len) end if - if (var_diags_opt == original_vars) then - - do i = tdims%i_start, tdims%i_end - ! calculate sh, don't interpolate with the surface flux or divide by 0 - if ( BL_diag%tke(i,j,k) > 1.0e-10_r_bl ) then - sh = rhokh(i,j,k) & - / ( rho_wet_tq(i,j,k-1) * elm(i,j,k) & - * sqrt( 2.0_r_bl * BL_diag%tke(i,j,k) ) ) - else - sh = small_sh - end if - if ( sh < small_sh ) sh = small_sh - ! calculate exner - exner = ( p_theta_levels(i,j,k-1) / pref )**kappa - ! calculate the variance, use gradient interpolated between levs 1 and 2 - sgm(i) = a_dqsdt(i,j,k-1)**2 * exner**2 * b2 * sh & - * elm(i,j,k)**2 * dsldz(i,j,k)**2 & - + a_qs(i,j,k-1)**2 * b2 * sh & - * elm(i,j,k)**2 * dqwdz(i,j,k)**2 & - - 2.0_r_bl * a_qs(i,j,k-1) * a_dqsdt(i,j,k-1) * exner * b2 & - * sh * elm(i,j,k)**2 * dsldz(i,j,k) * dqwdz(i,j,k) + do i = tdims%i_start, tdims%i_end + ! calculate the variance + sl_var = zero + qw_var = zero + sl_qw = zero + if ( BL_diag%tke(i,j,k) > small_tke ) then + ! vertical interpolation weights + weight1 = r_rho_levels(i,j,k) - r_rho_levels(i,j,k-1) + weight2 = r_theta_levels(i,j,k-1) - r_rho_levels(i,j,k-1) + weight3 = r_rho_levels(i,j,k) - r_theta_levels(i,j,k-1) + ! var_fac=b2*L/sqrt(TKE) + var_fac = b2 * rhokm(i,j,k) / ( weight1 * BL_diag%tke(i,j,k) * & + rho_wet_tq(i,j,k-1) * rho_mix_tq(i,j,k-1) ) + ! Note that flux*gradient can be negative so the absolute values + ! are used + qw_var= abs( -var_fac*( weight2 * fqw(i,j,k) * dqwdz(i,j,k) + & + weight3 * fqw(i,j,k-1)* dqwdz(i,j,k-1) ) ) + sl_var= abs( -var_fac*( weight2 * ftl(i,j,k) * dsldz(i,j,k) + & + weight3 * ftl(i,j,k-1)* dsldz(i,j,k-1) ) ) + sl_qw = - one_half * var_fac*( & + weight2*( ftl(i,j,k)*dqwdz(i,j,k) + fqw(i,j,k)*dsldz(i,j,k) ) + & + weight3*( ftl(i,j,k-1)*dqwdz(i,j,k-1) + fqw(i,j,k-1)*dsldz(i,j,k-1))& + ) if (BL_diag%l_slvar) then - BL_diag%slvar(i,j,k-1) = b2 * sh * elm(i,j,k)**2 * dsldz(i,j,k)**2 + BL_diag%slvar(i,j,k-1) = sl_var end if if (BL_diag%l_qwvar) then - BL_diag%qwvar(i,j,k-1) = b2 * sh * elm(i,j,k)**2 * dqwdz(i,j,k)**2 + BL_diag%qwvar(i,j,k-1) = qw_var end if if (BL_diag%l_slqw) then - BL_diag%slqw(i,j,k-1) = b2 * sh * elm(i,j,k)**2 * dsldz(i,j,k) & - * dqwdz(i,j,k) + BL_diag%slqw(i,j,k-1) = sl_qw end if - ! do this for safety, not sure if it's really needed - sgm(i) = sqrt ( max( sgm(i), zero ) ) - end do - - else ! var_diags_opt - - do i = tdims%i_start, tdims%i_end - ! calculate the variance - sl_var = zero - qw_var = zero - sl_qw = zero - if ( BL_diag%tke(i,j,k) > small_tke ) then - ! vertical interpolation weights - weight1 = r_rho_levels(i,j,k) - r_rho_levels(i,j,k-1) - weight2 = r_theta_levels(i,j,k-1) - r_rho_levels(i,j,k-1) - weight3 = r_rho_levels(i,j,k) - r_theta_levels(i,j,k-1) - ! var_fac=b2*L/sqrt(TKE) - var_fac = b2 * rhokm(i,j,k) / ( weight1 * BL_diag%tke(i,j,k) * & - rho_wet_tq(i,j,k-1) * rho_mix_tq(i,j,k-1) ) - ! Note that flux*gradient can be negative so the absolute values - ! are used - qw_var= abs( -var_fac*( weight2 * fqw(i,j,k) * dqwdz(i,j,k) + & - weight3 * fqw(i,j,k-1)* dqwdz(i,j,k-1) ) ) - sl_var= abs( -var_fac*( weight2 * ftl(i,j,k) * dsldz(i,j,k) + & - weight3 * ftl(i,j,k-1)* dsldz(i,j,k-1) ) ) - sl_qw = - one_half * var_fac*( & - weight2*( ftl(i,j,k)*dqwdz(i,j,k) + fqw(i,j,k)*dsldz(i,j,k) ) + & - weight3*( ftl(i,j,k-1)*dqwdz(i,j,k-1) + fqw(i,j,k-1)*dsldz(i,j,k-1))& - ) - if (BL_diag%l_slvar) then - BL_diag%slvar(i,j,k-1) = sl_var - end if - if (BL_diag%l_qwvar) then - BL_diag%qwvar(i,j,k-1) = qw_var - end if - if (BL_diag%l_slqw) then - BL_diag%slqw(i,j,k-1) = sl_qw - end if - end if - exner = ( p_theta_levels(i,j,k-1) / pref )**kappa - sgm(i) = a_dqsdt(i,j,k-1)**2 * exner**2 * sl_var & - + a_qs(i,j,k-1)**2 * qw_var & - - 2.0_r_bl * a_qs(i,j,k-1) * a_dqsdt(i,j,k-1) * exner * sl_qw - ! do this for safety, not sure if it's really needed - sgm(i) = sqrt ( max( sgm(i), zero ) ) + end if + exner = ( p_theta_levels(i,j,k-1) / pref )**kappa + sgm(i) = a_dqsdt(i,j,k-1)**2 * exner**2 * sl_var & + + a_qs(i,j,k-1)**2 * qw_var & + - 2.0_r_bl * a_qs(i,j,k-1) * a_dqsdt(i,j,k-1) * exner * sl_qw + ! do this for safety, not sure if it's really needed + sgm(i) = sqrt ( max( sgm(i), zero ) ) - end do !i - end if ! var_diags_opt + end do !i if (i_rhcpt == rhcpt_tke_based) then do i = tdims%i_start, tdims%i_end @@ -3057,110 +2922,61 @@ subroutine bdy_expl2 ( & call qsat_wat(qsw_arr,tl(:,j,k-1),p_theta_levels(:,j,k-1),tdims%i_len) end if - if (var_diags_opt == original_vars) then - - do i = tdims%i_start, tdims%i_end - ! calculate sh, don't divide by 0 - if ( BL_diag%tke(i,j,k) > 1.0e-10_r_bl ) then - weight1 = r_rho_levels(i,j,k) - r_rho_levels(i,j,k-1) - weight2 = r_theta_levels(i,j,k-1)-r_rho_levels(i,j,k-1) - weight3 = r_rho_levels(i,j,k) - r_theta_levels(i,j,k-1) - sh = ( weight2 * rhokh(i,j,k) + weight3 * rhokh(i,j,k-1) ) & - / ( weight1 * rho_wet_tq(i,j,k-1) * elm(i,j,k) & - * sqrt( 2.0_r_bl * BL_diag%tke(i,j,k) ) ) - else - sh = small_sh - end if - if ( sh < small_sh ) sh = small_sh - ! calculate exner - exner = ( p_theta_levels(i,j,k-1) / pref )**kappa - ! calculate the variance - sgm(i) = a_dqsdt(i,j,k-1)**2 * exner**2 * b2 * sh & - * elm(i,j,k)**2 * dsldzm(i,j,k)**2 & - + a_qs(i,j,k-1)**2 * b2 * sh & - * elm(i,j,k)**2 * dqwdzm(i,j,k)**2 & - - 2.0_r_bl * a_qs(i,j,k-1) * a_dqsdt(i,j,k-1) * exner * b2 & - * sh * elm(i,j,k)**2 * dsldzm(i,j,k) * dqwdzm(i,j,k) + do i = tdims%i_start, tdims%i_end + ! calculate the variance + sl_var = zero + qw_var = zero + sl_qw = zero + if ( BL_diag%tke(i,j,k) > small_tke ) then + ! vertical interpolation weights + weight1 = r_rho_levels(i,j,k) - r_rho_levels(i,j,k-1) + weight2 = r_theta_levels(i,j,k-1) - r_rho_levels(i,j,k-1) + weight3 = r_rho_levels(i,j,k) - r_theta_levels(i,j,k-1) + var_fac = b2 * rhokm(i,j,k) / ( weight1*BL_diag%tke(i,j,k) * & + rho_wet_tq(i,j,k-1) * rho_mix_tq(i,j,k-1)) + kp=k + km=k-1 + ! Don't use level ntml (or ntdsc) if disc_inv=2 as this indicates + ! the inversion has just risen and the gradients between ntml and + ! ntml-1 are likely to give excessive variances + if ( (kp == ntml(i,j) .and. sml_disc_inv(i,j) == 2) .or. & + (kp == ntdsc(i,j) .and. dsc_disc_inv(i,j) == 2) ) kp = km + if ( (km == ntml(i,j) .and. sml_disc_inv(i,j) == 2) .or. & + (km == ntdsc(i,j) .and. dsc_disc_inv(i,j) == 2) ) km = kp + ! Note that flux*gradient can be negative so the absolute values + ! are used + qw_var= abs( -var_fac*( weight2 * fqw(i,j,kp) * dqwdz(i,j,kp) + & + weight3 * fqw(i,j,km) * dqwdz(i,j,km) ) ) + sl_var= abs( -var_fac*( weight2 * ftl(i,j,kp) * dsldz(i,j,kp) + & + weight3 * ftl(i,j,km) * dsldz(i,j,km) ) ) + sl_qw = - one_half * var_fac*( & + weight2*( ftl(i,j,k)*dqwdz(i,j,k) + fqw(i,j,k)*dsldz(i,j,k) ) + & + weight3*( ftl(i,j,k-1)*dqwdz(i,j,k-1) + fqw(i,j,k-1)*dsldz(i,j,k-1))& + ) if (BL_diag%l_slvar) then - BL_diag%slvar(i,j,k-1) = b2 * sh * elm(i,j,k)**2 * dsldz(i,j,k)**2 + BL_diag%slvar(i,j,k-1) = sl_var end if if (BL_diag%l_qwvar) then - BL_diag%qwvar(i,j,k-1) = b2 * sh * elm(i,j,k)**2 * dqwdz(i,j,k)**2 + BL_diag%qwvar(i,j,k-1) = qw_var end if if (BL_diag%l_slqw) then - BL_diag%slqw(i,j,k-1) = b2 * sh * elm(i,j,k)**2 * dsldzm(i,j,k) & - * dqwdz(i,j,k) + BL_diag%slqw(i,j,k-1) = sl_qw end if - end do !i - if (i_rhcpt == rhcpt_tke_based) then - do i = tdims%i_start, tdims%i_end - ! do this for safety, not sure if it's really needed - sgm(i) = sqrt ( max( sgm(i), zero ) ) - ! calculate rhcrit, with appropriate limits - rhcpt(i,j,k-1) = min( max_rhcpt(i,j), max( min_rhcpt(i,j), & - one - root6 * sgm(i) / (a_qs(i,j,k-1) * qsw_arr(i)))) - end do !i end if - - else ! var_diags_opt - + exner = ( p_theta_levels(i,j,k-1) / pref )**kappa + sgm(i) = a_dqsdt(i,j,k-1)**2 * exner**2 * sl_var & + + a_qs(i,j,k-1)**2 * qw_var & + - 2.0_r_bl * a_qs(i,j,k-1) * a_dqsdt(i,j,k-1) * exner * sl_qw + end do !i + if (i_rhcpt == rhcpt_tke_based) then do i = tdims%i_start, tdims%i_end - ! calculate the variance - sl_var = zero - qw_var = zero - sl_qw = zero - if ( BL_diag%tke(i,j,k) > small_tke ) then - ! vertical interpolation weights - weight1 = r_rho_levels(i,j,k) - r_rho_levels(i,j,k-1) - weight2 = r_theta_levels(i,j,k-1) - r_rho_levels(i,j,k-1) - weight3 = r_rho_levels(i,j,k) - r_theta_levels(i,j,k-1) - var_fac = b2 * rhokm(i,j,k) / ( weight1*BL_diag%tke(i,j,k) * & - rho_wet_tq(i,j,k-1) * rho_mix_tq(i,j,k-1)) - kp=k - km=k-1 - ! Don't use level ntml (or ntdsc) if disc_inv=2 as this indicates - ! the inversion has just risen and the gradients between ntml and - ! ntml-1 are likely to give excessive variances - if ( (kp == ntml(i,j) .and. sml_disc_inv(i,j) == 2) .or. & - (kp == ntdsc(i,j) .and. dsc_disc_inv(i,j) == 2) ) kp = km - if ( (km == ntml(i,j) .and. sml_disc_inv(i,j) == 2) .or. & - (km == ntdsc(i,j) .and. dsc_disc_inv(i,j) == 2) ) km = kp - ! Note that flux*gradient can be negative so the absolute values - ! are used - qw_var= abs( -var_fac*( weight2 * fqw(i,j,kp) * dqwdz(i,j,kp) + & - weight3 * fqw(i,j,km) * dqwdz(i,j,km) ) ) - sl_var= abs( -var_fac*( weight2 * ftl(i,j,kp) * dsldz(i,j,kp) + & - weight3 * ftl(i,j,km) * dsldz(i,j,km) ) ) - sl_qw = - one_half * var_fac*( & - weight2*( ftl(i,j,k)*dqwdz(i,j,k) + fqw(i,j,k)*dsldz(i,j,k) ) + & - weight3*( ftl(i,j,k-1)*dqwdz(i,j,k-1) + fqw(i,j,k-1)*dsldz(i,j,k-1))& - ) - if (BL_diag%l_slvar) then - BL_diag%slvar(i,j,k-1) = sl_var - end if - if (BL_diag%l_qwvar) then - BL_diag%qwvar(i,j,k-1) = qw_var - end if - if (BL_diag%l_slqw) then - BL_diag%slqw(i,j,k-1) = sl_qw - end if - end if - exner = ( p_theta_levels(i,j,k-1) / pref )**kappa - sgm(i) = a_dqsdt(i,j,k-1)**2 * exner**2 * sl_var & - + a_qs(i,j,k-1)**2 * qw_var & - - 2.0_r_bl * a_qs(i,j,k-1) * a_dqsdt(i,j,k-1) * exner * sl_qw + ! do this for safety, not sure if it's really needed + sgm(i) = sqrt ( max( sgm(i), zero ) ) + ! calculate rhcrit, with appropriate limits + rhcpt(i,j,k-1) = min( max_rhcpt(i,j), max( min_rhcpt(i,j), & + one - root6 * sgm(i) / (a_qs(i,j,k-1) * qsw_arr(i)))) end do !i - if (i_rhcpt == rhcpt_tke_based) then - do i = tdims%i_start, tdims%i_end - ! do this for safety, not sure if it's really needed - sgm(i) = sqrt ( max( sgm(i), zero ) ) - ! calculate rhcrit, with appropriate limits - rhcpt(i,j,k-1) = min( max_rhcpt(i,j), max( min_rhcpt(i,j), & - one - root6 * sgm(i) / (a_qs(i,j,k-1) * qsw_arr(i)))) - end do !i - end if - - end if ! var_diags_opt + end if end do !j !$OMP end do NOWAIT diff --git a/science/physics_schemes/source/boundary_layer/bdy_impl3.F90 b/science/physics_schemes/source/boundary_layer/bdy_impl3.F90 index 0a7ca2b94..c18f9f550 100644 --- a/science/physics_schemes/source/boundary_layer/bdy_impl3.F90 +++ b/science/physics_schemes/source/boundary_layer/bdy_impl3.F90 @@ -51,7 +51,7 @@ subroutine bdy_impl3 ( & use yomhook, only: lhook, dr_hook use parkind1, only: jprb, jpim -!$ use omp_lib, only: omp_get_num_threads +!$ use omp_lib, only: omp_get_max_threads implicit none @@ -317,12 +317,15 @@ subroutine bdy_impl3 ( & ! Loop counter (horizontal field index). k, & ! Loop counter (vertical index). - omp_block, & + tdims_omp_block, & ! omp block length - jj, & + tdims_seg_block, & + ! omp segment length + ii, & ! omp block loop counter - l + l, & ! vector counter + max_threads integer(kind=jpim), parameter :: zhook_in = 0 integer(kind=jpim), parameter :: zhook_out = 1 @@ -333,9 +336,16 @@ subroutine bdy_impl3 ( & if (lhook) call dr_hook(ModuleName//':'//RoutineName,zhook_in,zhook_handle) -!$OMP PARALLEL DEFAULT(none) SHARED(l_correct,bl_levels,tdims, & -!$OMP dqw_nt,dtl_nt,q_latest,qcl_latest, dtrdz_v,dtrdz_u,udims, rdz_v, & -!$OMP gamma1,q,qcl,qcf,t_latest,t,ftl,rhokh,dtl,rdz_charney_grid,dqw, & +blm1 = bl_levels-1 + +max_threads = 1 +!$ max_threads = omp_get_max_threads() +tdims_omp_block = ceiling(real(tdims%i_len)/max_threads) +tdims_seg_block = min(tdims_omp_block, tdims%i_len) + +!$OMP PARALLEL DEFAULT(none) SHARED(tdims_seg_block,l_correct,bl_levels, & +!$OMP blm1,tdims, dqw_nt,dtl_nt,q_latest,qcl_latest,dtrdz_v,dtrdz_u,udims, & +!$OMP rdz_v,gamma1,q,qcl,qcf,t_latest,t,ftl,rhokh,dtl,rdz_charney_grid,dqw, & !$OMP tau_x,rhokm_u,du,rdz_u,vdims,tau_y,dv, qcf_latest, & !$OMP qw,tl,r_theta_levels,r_theta_u,r_theta_v,r_rho_levels,fqw, & !$OMP dtrdz_charney_grid,gamma2,ct_ctq,dqw1,dtl1,ctctq1,model_type, & @@ -344,7 +354,7 @@ subroutine bdy_impl3 ( & !$OMP ct_prod, cu_prod, cv_prod,k_blend_tq,k_blend_u,k_blend_v, & !$OMP gamma_in,cq_cm_u,cq_cm_v,du_nt,dv_nt,rhokm_v,lcrcp,lsrcp) & !$OMP private(k,j,i,r_sq,rbt,temp,temp_u,temp_v,l,temp_out,temp_u_out, & -!$OMP temp_v_out,at,blm1,am,rbm,rr_sq,jj,omp_block,gamma1_uv,gamma2_uv) +!$OMP temp_v_out,at,am,rbm,rr_sq,ii,gamma1_uv,gamma2_uv) if ( l_correct ) then @@ -402,8 +412,6 @@ subroutine bdy_impl3 ( & end if ! l_correct -blm1 = bl_levels-1 - !----------------------------------------------------------------------- ! 1.0 Interpolate r_theta_levels to U,V columns !----------------------------------------------------------------------- @@ -443,15 +451,12 @@ subroutine bdy_impl3 ( & end do !$OMP end do -omp_block = tdims%j_end -!$ omp_block = ceiling(tdims%j_end/real(omp_get_num_threads())) - !$OMP do SCHEDULE(STATIC) -do jj = tdims%j_start, tdims%j_end, omp_block +do ii = tdims%i_start, tdims%i_end, tdims_seg_block do k = blm1, 2, -1 l = 0 - do j = jj, min(jj+omp_block-1, tdims%j_end) - do i = tdims%i_start, tdims%i_end + do j = tdims%j_start, tdims%j_end + do i = ii, min(ii+tdims_seg_block -1, tdims%i_end) r_sq = r_rho_levels(i,j,k)*r_rho_levels(i,j,k) rr_sq = r_rho_levels(i,j,k+1)*r_rho_levels(i,j,k+1) dqw(i,j,k) = ( -dtrdz_charney_grid(i,j,k)* & @@ -476,8 +481,8 @@ subroutine bdy_impl3 ( & call oneover_v(l, temp, temp_out) l = 0 - do j = jj, min(jj+omp_block-1, tdims%j_end) - do i = tdims%i_start, tdims%i_end + do j = tdims%j_start, tdims%j_end + do i = ii, min(ii+tdims_seg_block -1, tdims%i_end) l = l + 1 dqw(i,j,k) = temp_out(l) * dqw(i,j,k) dtl(i,j,k) = temp_out(l) * dtl(i,j,k) @@ -534,11 +539,11 @@ subroutine bdy_impl3 ( & !$OMP end do !$OMP do SCHEDULE(STATIC) - do jj = tdims%j_start, tdims%j_end, omp_block + do ii = tdims%i_start, tdims%i_end, tdims_seg_block do k = blm1, 2, -1 l = 0 - do j = jj, min(jj+omp_block-1, tdims%j_end) - do i = tdims%i_start, tdims%i_end + do j = tdims%j_start, tdims%j_end + do i = ii, min(ii+tdims_seg_block -1, tdims%i_end) r_sq = r_rho_levels(i,j,k)*r_rho_levels(i,j,k) rr_sq = r_rho_levels(i,j,k+1)*r_rho_levels(i,j,k+1) dqw1(i,j,k) = -dtrdz_charney_grid(i,j,k) * & @@ -560,8 +565,8 @@ subroutine bdy_impl3 ( & call oneover_v(l, temp, temp_out) l = 0 - do j = jj, min(jj+omp_block-1, tdims%j_end) - do i = tdims%i_start, tdims%i_end + do j = tdims%j_start, tdims%j_end + do i = ii, min(ii+tdims_seg_block -1, tdims%i_end) l = l + 1 dqw1(i,j,k) = temp_out(l) * dqw1(i,j,k) dtl1(i,j,k) = temp_out(l) * dtl1(i,j,k) diff --git a/science/physics_schemes/source/boundary_layer/bdy_impl4.F90 b/science/physics_schemes/source/boundary_layer/bdy_impl4.F90 index 088653df1..d482b53d9 100644 --- a/science/physics_schemes/source/boundary_layer/bdy_impl4.F90 +++ b/science/physics_schemes/source/boundary_layer/bdy_impl4.F90 @@ -41,7 +41,7 @@ subroutine bdy_impl4 ( & use atm_fields_bounds_mod, only: & udims, vdims, udims_s, vdims_s, tdims, pdims, tdims_l use bl_diags_mod, only: strnewbldiag - +use tuning_segments_mod, only: bl_segment_size use model_domain_mod, only: model_type, mt_single_column use planet_constants_mod, only: cp => cp_bl use yomhook, only: lhook, dr_hook @@ -196,7 +196,7 @@ subroutine bdy_impl4 ( & ! LOCAL Loop counter (horizontal field index). k ! LOCAL Loop counter (vertical level index). -integer :: jj, j_block ! omp blocking variables +integer :: ii, tdims_omp_block, tdims_seg_block ! omp blocking variables integer(kind=jpim), parameter :: zhook_in = 0 integer(kind=jpim), parameter :: zhook_out = 1 @@ -206,9 +206,10 @@ subroutine bdy_impl4 ( & if (lhook) call dr_hook(ModuleName//':'//RoutineName,zhook_in,zhook_handle) -j_block = 4 +tdims_omp_block = bl_segment_size +tdims_seg_block = min(tdims_omp_block, tdims%i_len) -!$OMP PARALLEL DEFAULT(SHARED) private(i,j,k,jj,at,rbt,gamma1_uv, & +!$OMP PARALLEL DEFAULT(SHARED) private(i,j,k,ii,at,rbt,gamma1_uv, & !$OMP gamma2_uv,r_sq) if ( .not. l_correct ) then ! 1st stage: predictor @@ -266,10 +267,10 @@ subroutine bdy_impl4 ( & !$OMP end do !$OMP do SCHEDULE(STATIC) -do jj = tdims%j_start, tdims%j_end, j_block +do ii = tdims%j_start, tdims%i_end, tdims_seg_block do k = 2, bl_levels - do j = jj, min(jj+j_block-1,tdims%j_end) - do i = tdims%i_start, tdims%i_end + do j = tdims%j_start, tdims%j_end + do i = ii, min(ii+tdims_seg_block-1,tdims%i_end) dtl(i,j,k) = dtl(i,j,k) - ct_ctq(i,j,k)*dtl(i,j,k-1) tl(i,j,k) = tl(i,j,k) + dtl(i,j,k) dqw(i,j,k) = dqw(i,j,k) - ct_ctq(i,j,k)*dqw(i,j,k-1) diff --git a/science/physics_schemes/source/boundary_layer/bl_option_mod.F90 b/science/physics_schemes/source/boundary_layer/bl_option_mod.F90 index d6fccca90..faaa5a96a 100644 --- a/science/physics_schemes/source/boundary_layer/bl_option_mod.F90 +++ b/science/physics_schemes/source/boundary_layer/bl_option_mod.F90 @@ -64,7 +64,7 @@ module bl_option_mod integer, parameter :: sharp_sea_long_land = 2 integer, parameter :: mes_tails = 3 integer, parameter :: louis_tails = 4 -integer, parameter :: depth_based = 5 +integer, parameter :: depth_based = 5 ! not available in LFRic integer, parameter :: sharp_sea_mes_land = 6 integer, parameter :: lem_stability = 7 integer, parameter :: sharp_sea_louis_land = 8 @@ -291,11 +291,6 @@ module bl_option_mod ! 13 Improved method to calculate cloud-top radiative flux jump logical :: l_new_kcloudtop = .false. -! 14 Switch for alternative TKE and variance diagnostics -integer :: var_diags_opt = imdi -integer, parameter :: original_vars = 0 -integer, parameter :: split_tke_and_inv = 1 - ! 15 Multiplicative tuning factor in TKE diagnosis, usually 1.0 real(kind=r_bl) :: tke_diag_fac = rmdi @@ -503,12 +498,6 @@ module bl_option_mod ! Switch for coupled gradient method in Equilibrium SBL model logical, parameter :: L_SBLco = .true. -! LambdaM=2*LambdaH (operational setting) -logical, parameter :: l_lambdam2 = .false. - -! Lambdas not reduced above NTML_LOCAL+1 -logical, parameter :: l_full_lambdas = .false. - ! logical for whether to skip calculations based on start of timestep ! quantities when using semi-lagrangian cycling with Endgame ! This is set to true in dynamics_input_mod as Endgame always uses it, @@ -531,7 +520,7 @@ module bl_option_mod l_use_surf_in_ri, lambda_min_nml, ritrans, c_gust, & dzrad_disc_opt, num_sweeps_bflux, l_converge_ga, & local_fa, Keep_Ri_FA, l_bl_mix_qcf, l_conv_tke, l_use_var_fixes, & - l_reset_neg_q, var_diags_opt, tke_diag_fac, i_interp_local, & + l_reset_neg_q, tke_diag_fac, i_interp_local, & sg_orog_mixing, fric_heating, calc_prob_of_vis, z_nl_bl_levels, & idyndiag, zhloc_depth_fac, flux_grad, entr_smooth_dec, & sc_diag_opt, kprof_cu, bl_res_inv, blending_option, & @@ -632,8 +621,6 @@ subroutine print_nlist_run_bl() call umprint(linebuffer,src='bl_option_mod') write(linebuffer,'(A,L1)') 'l_converge_ga = ',l_converge_ga call umprint(linebuffer,src='bl_option_mod') -write(linebuffer,'(A,I4)') 'var_diags_opt = ',var_diags_opt -call umprint(linebuffer,src='bl_option_mod') write(linebuffer,'(A,L1)') 'l_use_var_fixes = ',l_use_var_fixes call umprint(linebuffer,src='bl_option_mod') write(linebuffer,'(A,ES12.4)') 'tke_diag_fac = ',tke_diag_fac diff --git a/science/physics_schemes/source/boundary_layer/ex_coef.F90 b/science/physics_schemes/source/boundary_layer/ex_coef.F90 index fd9ffe3e1..01164c314 100644 --- a/science/physics_schemes/source/boundary_layer/ex_coef.F90 +++ b/science/physics_schemes/source/boundary_layer/ex_coef.F90 @@ -24,11 +24,10 @@ module ex_coef_mod subroutine ex_coef ( & ! in levels/logicals - bl_levels,k_log_layr,nSCMDpkgs,L_SCMDiags, BL_diag, & + bl_levels, k_log_layr, BL_diag, & ! in fields - sigma_h,flandg,dbdz,dvdzm,ri,rho_wet_tq,z_uv,z_tq,z0m,h_blend,zhpar, & - ntpar,ntml_nl,ntdsc,nbdsc,u_p,v_p,v_s,fb_surf,qw,tl,l_shallow_cth,rmlmax2, & - rneutml_sq, delta_smag, & + sigma_h,flandg,dvdzm,ri,rho_wet_tq,z_uv,z_tq,z0m,zhpar,ntpar, & + ntml_nl,ntdsc,nbdsc,l_shallow_cth,rmlmax2,rneutml_sq, delta_smag, & ! in/out fields cumulus,weight_1dbl, & ! out fields @@ -39,18 +38,17 @@ subroutine ex_coef ( & use atm_fields_bounds_mod, only: pdims, tdims, pdims_s use bl_diags_mod, only: strnewbldiag use bl_option_mod, only: WeightLouisToLong, Variable_RiC, cbl_op, & - sg_orog_mixing, ricrit_sharp, pr_max, l_lambdam2, l_full_lambdas, & + sg_orog_mixing, ricrit_sharp, pr_max, & local_fa,Prandtl,ishear_bl,L_SBLco,Muw_SBL,Mwt_SBL,sbl_op, & - LockMailhot2004, depth_based, lem_stability, lem_std, lem_conven, & + LockMailhot2004, lem_stability, lem_std, lem_conven, & lem_adjust, cbl_mix_fac_nml, & off, on, sharpest, sharp_sea_long_land, sharp_sea_mes_land, & louis_tails, sharp_sea_louis_land, long_tails, mes_tails, ritrans, & - neut_cbl, equilibrium_sbl, lambda_min_nml, lambda_max_nml, & + neut_cbl, lambda_min_nml, lambda_max_nml, & lambda_fac, beta_bl, beta_fa, rlinfac, linear0, & to_sharp_across_1km, ntml_level_corrn, free_trop_layers, two_thirds, & blending_option, blend_except_cu, blend_gridindep_fa, blend_cth_shcu_only, & - extended_tail, sg_shear_enh_lambda, l_use_var_fixes, var_diags_opt, & - split_tke_and_inv, zero, one, one_half + extended_tail, zero, one, one_half use conversions_mod, only: pi => pi_bl use gen_phys_inputs_mod, only: l_mr_physics @@ -63,8 +61,6 @@ subroutine ex_coef ( & use turb_diff_mod, only: l_subfilter_vert, l_subfilter_horiz use model_domain_mod, only: model_type, mt_single_column -use s_scmop_mod, only: default_streams, & - t_avg, d_sl, scmdiag_bl use yomhook, only: lhook, dr_hook use parkind1, only: jprb, jpim @@ -98,20 +94,6 @@ subroutine ex_coef ( & bl_levels), & ! in density on theta levels; ! used in RHOKM so wet density - dbdz(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end, & - 2:bl_levels), & - ! in Buoyancy gradient across lower - ! interface of layer. - u_p(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end,bl_levels), & - ! in Westerly wind component horizontally - ! interpolated to P-grid. (m/s) - v_p(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end,bl_levels), & - ! in Southerly wind component horizontally - ! interpolated to P-grid. (m/s) - qw(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end,bl_levels), & - ! in Total water content (kg per kg air). - tl(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end,bl_levels), & - ! in Liquid/frozen water temperature (K). rmlmax2(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end,bl_levels), & ! in Square of asymptotic mixing length for Smagorinsky scheme z_uv(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end,bl_levels+1), & @@ -123,18 +105,11 @@ subroutine ex_coef ( & ! in Height of top of initial parcel ascent z0m(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & ! in Roughness length for momentum (m). - h_blend(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & - ! in Blending height for effective - ! roughness length scheme dvdzm(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end, & 2:bl_levels), & ! in Modulus of wind shear. ri(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end,2:bl_levels), & ! in Local Richardson number. - v_s(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & - ! in Surface friction velocity (m/s) - fb_surf(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & - ! in Surface buoyancy flux over density (m^2/s^3). flandg(pdims_s%i_start:pdims_s%i_end,pdims_s%j_start:pdims_s%j_end), & ! in Land fraction on all tiles. rneutml_sq(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end,bl_levels), & @@ -146,13 +121,6 @@ subroutine ex_coef ( & l_shallow_cth(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end) ! in Flag to indicate shallow convection based on cl-top -! Additional variables for SCM diagnostics which are dummy in full UM -integer, intent(in) :: & - nSCMDpkgs ! in No of SCM diagnostics packages - -logical, intent(in) :: & - L_SCMDiags(nSCMDpkgs) ! Logicals for SCM diagnostics packages - ! Declaration of new BL diagnostics. type (strnewbldiag), intent(in out) :: BL_diag @@ -216,7 +184,7 @@ subroutine ex_coef ( & character(len=*), parameter :: RoutineName = 'EX_COEF' -real(kind=r_bl) :: eh,em,g0,dh,dm,a_lambda,r_c_tke +real(kind=r_bl) :: eh,em,g0,dh,dm,r_c_tke real(kind=r_bl) :: subbmin,subbmax,subcmin,subcmax real(kind=r_bl) :: a_ri,b_ri @@ -225,8 +193,6 @@ subroutine ex_coef ( & ! Used in calc of stability function FH. em=4.0_r_bl, & ! Used in calc of stability function FM. - a_lambda=2.0_r_bl, & - ! used in calc of LAMBDA_EFF r_c_tke=one/0.41_r_bl & ! used in calc of TKE (1/stress-energy ratio, see UMDP25) ) @@ -246,20 +212,6 @@ subroutine ex_coef ( & ! Used in calc of unstability function FM. ) -! Equilibrium SBL model constants -real(kind=r_bl) :: RtestMin -integer :: gn,NGz,kMINh -parameter ( & - RtestMin=zero, & - ! Threshold for Rtest - gn=19, & - ! Size of "G"-tables (No. HonL values) - NGz=90, & - ! No. z/h steps in each "G" integration - kMINh=2 & - ! Level of minimum SBL height (>=2) -) - ! Define local storage. real(kind=r_bl) :: & ricrit(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & @@ -268,21 +220,6 @@ subroutine ex_coef ( & ! 2D variable for SBL stabiliy function options sharp(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & ! 2D variable for SHARP stabiliy function - invMOsurf(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & - ! Inverse of sfce M-O length - ! Note: Inverse is used so that neutral conditions - ! can be handled (M-O length --> infinity) - zh_esbl(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & - ! Ht of equilib SBL (sub-grid - HLtab(gn), & - ! Lookup tables (Gx calcs - GHsav(gn,NGz),gmsav(gn,NGz), & - ! in equilib SBL scheme) - THv_TQ(tdims%i_start:tdims%i_end,tdims%j_start:tdims%j_end, & - bl_levels), & - ! Virtual potential temperature on theta levels - THv(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end,bl_levels), & - ! THv_TQ interpolated to U,V levels prandtl_number(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & ! = KM/KH (currently only calculated for stable) BL_weight(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end, & @@ -296,10 +233,6 @@ subroutine ex_coef ( & weight_bltop(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end) ! weight_1dbl at the top of the PBL -integer :: & - ntml_esbl(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end) - ! No. UV-levels inside equilibrium SBL - logical :: & topbl(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end) ! Flag for having reached the @@ -319,25 +252,12 @@ subroutine ex_coef ( & ! z/sigma_h rpr ! !/Pr -! Variables for boundary layer depth based formulation -real(kind=r_bl) :: & - h_tkeb(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & - ! TKE budget based BL depth - MOsurf(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end), & - ! surface Obukhov length - diff_min(pdims%i_start:pdims%i_end,pdims%j_start:pdims%j_end) real(kind=r_bl) :: & - h_est, & - rifb, & - ! Bulk flux Richardson number pr_n, & ! neutral Prandtl number - r_pr_n, & + r_pr_n ! 1 / neutral Prandtl number - m_tau,m_buoy, & - ! Indices for implied stress and buoyancy flux profs - ind,diff real(kind=r_bl) :: & subb, subc, subg, ric, ricinv, rifac @@ -373,12 +293,7 @@ subroutine ex_coef ( & ! top of boundary layer mixing zfa, & ! height to use beta_fa in blendin - lambda_eff ! Effective mixing length used with effective - ! roughness length scheme. - -!Equilibrium SBL model temporary real scalar variables -real(kind=r_bl) :: & - km, u1, zz + zz integer :: & i,j, & @@ -388,38 +303,15 @@ subroutine ex_coef ( & kb, kt ! Base and top level of unstable Ri layers -!Equilibrium SBL model temporary integer scalar variables -integer :: & - kZtop,kZbot,gk,kG0, & - ! Temporary loop counters - iERRSBL ! SBLequil error status - -!Equilibrium SBL model logical variables logical :: & - GcalcDone, & - ! Calculation of Gx values has been performed - subcrit, & - ! flag for being in a subcritical ri layer - subgrid ! Will perform subgrid SBL depth calculation - -!Switch to enable subgrid SBL depth diagnosis -logical :: sg_enabled -parameter (sg_enabled=.true.) - -!Equilibrium SBL model SAVED variables -save HLtab,GHsav,gmsav,GcalcDone - -!Equilibrium SBL model data statements -data HLtab /0.0001_r_bl,0.001_r_bl,0.002_r_bl,0.005_r_bl,0.01_r_bl,0.02_r_bl, & - 0.05_r_bl,0.1_r_bl,0.2_r_bl,one_half,one,2.0_r_bl,5.0_r_bl, & - 10.0_r_bl,20.0_r_bl,50.0_r_bl,100.0_r_bl,200.0_r_bl,500.0_r_bl/ -data GcalcDone /.false./ + subcrit ! flag for being in a subcritical ri layer integer(kind=jpim), parameter :: zhook_in = 0 integer(kind=jpim), parameter :: zhook_out = 1 real(kind=jprb) :: zhook_handle if (lhook) call dr_hook(ModuleName//':'//RoutineName,zhook_in,zhook_handle) + !----------------------------------------------------------------------- ! if stochastic physics random parameters is used set the parameter ! used to vary the stability function to a perturbed value, if not @@ -443,7 +335,6 @@ subroutine ex_coef ( & !--------------------------------------------------------------- pr_n = one if (Prandtl == LockMailhot2004) pr_n = 0.7_r_bl -if (sbl_op == depth_based) pr_n = 0.7_r_bl ! Use pr_n=0.7 if any LEM stability function selected if (sbl_op == lem_stability .or. cbl_op == lem_std & .or. cbl_op == lem_conven & @@ -496,7 +387,7 @@ subroutine ex_coef ( & ricinv = one/ric rlambda_fac=one/lambda_fac -!$OMP PARALLEL DEFAULT(SHARED) private ( i, j, k, z_scale, zpr ) +!$OMP PARALLEL DEFAULT(SHARED) private ( i, j ) !$OMP do SCHEDULE(STATIC) do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end @@ -504,7 +395,6 @@ subroutine ex_coef ( & ! 0. Initialise flag for having reached top of turbulently mixed layer !----------------------------------------------------------------------- topbl(i,j) = .false. - prandtl_number(i,j) = pr_n ! initialise blending weight at top of BL to one weight_bltop(i,j) = one @@ -512,97 +402,6 @@ subroutine ex_coef ( & end do !$OMP end do NOWAIT !----------------------------------------------------------------------- -! Set-up a BL weighting function, =1 near the ground (ie in the BL) -! =0 in the free troposphere -! Rate and height at which transition occurs varys depending on choices: -!----------------------------------------------------------------------- -!$OMP do SCHEDULE(STATIC) -do k = 1, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - BL_weight(i,j,k) = one - end do - end do -end do -!$OMP end do - -if (local_fa == to_sharp_across_1km) then - !--------------------------------------------------------- - ! Additional code to allow the local Ri scheme to use - ! SHARPEST in the free atmosphere, ie above the BL top, - ! regardless of the tail option selected above. - ! Set Z_SCALE to 1km to mimic old value of BL_LEVELS, - ! gives BL_weight~0 by 2km, ~0.95 at 500m - !--------------------------------------------------------- - z_scale = 1000.0_r_bl -!$OMP do SCHEDULE(STATIC) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - zpr = z_tq(i,j,k-1)/z_scale - BL_weight(i,j,k) = one_half*(one - tanh(3.0_r_bl*(zpr-one) ) ) - end do - end do - end do -!$OMP end do NOWAIT -end if - -if (sg_orog_mixing /= off) then - !----------------------------------------------------------------- - ! Subgrid orographic height dependence for SBL tail (option 1) - ! or orographic dependence of mixing lengths, lambdam,h (opt 2) - ! Gives BL_weight~[1,0.95,0.5,0] at ZPR=[0,0.6,1,1.7] - !---------------------------------------------------------------- -!$OMP do SCHEDULE(STATIC) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - if (sigma_h(i,j) > one ) then - zpr = z_tq(i,j,k-1)/sigma_h(i,j) - BL_weight(i,j,k) = one_half*( one - & - tanh(4.0_r_bl*(zpr-one) ) ) - end if - end do - end do - end do -!$OMP end do NOWAIT -end if - -if (l_use_var_fixes) then -!$OMP do SCHEDULE(STATIC) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - turb_length(i,j,k) = lambda_min*rlambda_fac - end do - end do - end do -!$OMP end do NOWAIT - if (blending_option == blend_cth_shcu_only) then - ! use Smag mixing length as background length scale if smaller - ! than lambda_min (ie ignore lambda_min for high res simulations) -!$OMP do SCHEDULE(STATIC) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - turb_length(i,j,k) = min( turb_length(i,j,k), sqrt(rmlmax2(i,j,k)) ) - end do - end do - end do -!$OMP end do NOWAIT - end if -else -!$OMP do SCHEDULE(STATIC) - do k = 2, bl_levels - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - turb_length(i,j,k)=lambda_min - end do - end do - end do -!$OMP end do NOWAIT -end if -!----------------------------------------------------------------------- ! Set critical Richardson number !----------------------------------------------------------------------- if (l_rp2) then @@ -699,20 +498,18 @@ subroutine ex_coef ( & end if !----------------------------------------------------------------------- -! 1.1 Loop over levels calculating Richardson numbers. +! 1.1 Use Richardson number profile to calculate BL depth, zh !----------------------------------------------------------------------- - !$OMP PARALLEL DEFAULT(none) private(k,j,i) & !$OMP SHARED(bl_levels,pdims,topbl,ri,ricrit,local_fa,ntml_local,zh_local,z_uv) do k = 2, bl_levels !$OMP do SCHEDULE(STATIC) do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end - !------------------------------------------------------------------ - ! 1.2 If either a stable layer (Ri>RiCrit) or the maximum BL - ! height has been reached, set boundary layer height (ZH_LOCAL) to - ! the height of the lower boundary of the current layer + ! If either a stable layer (Ri>RiCrit) or the maximum BL + ! height has been reached, set boundary layer height (ZH_LOCAL) to + ! the height of the lower boundary of the current layer !------------------------------------------------------------------ if ( .not. topbl(i,j) .and. & (ri(i,j,k) > ricrit(i,j) .or. k == bl_levels) ) then @@ -741,18 +538,17 @@ subroutine ex_coef ( & end if !----------------------------------------------------------------------- -! In CUMULUS layers the local scheme is capped at the LCL (given in -! this case by NTML_NL). Save local BL depth as SCM diagnostic. -!----------------------------------------------------------------------- -!----------------------------------------------------------------------- -! If NTML_LOCAL is greater than the top of the parcel ascent (NTPAR) -! for a cumulus-capped layer, shear driven mixing is allowed to -! dominate (if ISHEAR_BL=1 selected) +! 1.2 In CUMULUS layers the local scheme is capped at the LCL (given in +! this case by NTML_NL). +! If NTML_LOCAL is greater than the top of the parcel ascent (NTPAR) +! for a cumulus-capped layer, shear driven mixing is allowed to +! dominate (if ISHEAR_BL=1 selected) !----------------------------------------------------------------------- !$OMP PARALLEL DEFAULT(none) & -!$OMP SHARED( pdims, ishear_bl, l_use_var_fixes, ntml_local, ntpar, cumulus, & -!$OMP ntml_nl, zh_local, z_uv ) & -!$OMP private( i, j ) +!$OMP SHARED( pdims, ishear_bl, ntml_local, ntpar, cumulus, & +!$OMP bl_levels, lambda_min, rlambda_fac, & +!$OMP turb_length, blending_option, rmlmax2) & +!$OMP private( i, j, k ) !$OMP do SCHEDULE(STATIC) do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end @@ -762,30 +558,37 @@ subroutine ex_coef ( & end do end do !$OMP end do - -if ( .not. l_use_var_fixes ) then - ! Use sub-cloud layer as local PBL depth (as for non-local). - ! Found to give large TKE and variances with new diagnostics - ! and isn't particularly justifiable +!----------------------------------------------------------------------- +! 1.3 Search for sub-critical layers above the PBL and set the +! mixing length to scale with these layer depths +!----------------------------------------------------------------------- !$OMP do SCHEDULE(STATIC) +do k = 2, bl_levels do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end - if ( cumulus(i,j) ) then - ntml_local(i,j) = ntml_nl(i,j) - zh_local(i,j) = z_uv(i,j,ntml_local(i,j)+1) - end if + turb_length(i,j,k) = lambda_min*rlambda_fac end do end do -!$OMP end do +end do +!$OMP end do NOWAIT +if (blending_option == blend_cth_shcu_only) then + ! use Smag mixing length as background length scale if smaller + ! than lambda_min (ie ignore lambda_min for high res simulations) +!$OMP do SCHEDULE(STATIC) + do k = 2, bl_levels + do j = pdims%j_start, pdims%j_end + do i = pdims%i_start, pdims%i_end + turb_length(i,j,k) = min( turb_length(i,j,k), sqrt(rmlmax2(i,j,k)) ) + end do + end do + end do +!$OMP end do NOWAIT end if !$OMP end PARALLEL -!----------------------------------------------------------------------- -! 1.3 Search for sub-critical layers above the PBL and set the -! mixing length to scale with these layer depths -!----------------------------------------------------------------------- + if (local_fa == free_trop_layers) then !$OMP PARALLEL do DEFAULT(none) SCHEDULE(STATIC) & -!$OMP SHARED( pdims, bl_levels, ntml_local, ri, ricrit, z_uv, l_use_var_fixes, & +!$OMP SHARED( pdims, bl_levels, ntml_local, ri, ricrit, z_uv, & !$OMP turb_length, rlambda_fac, lambda_min ) & !$OMP private( i, j, k, subcrit, kb, kt, kl, turb_length_layer ) do j = pdims%j_start, pdims%j_end @@ -806,17 +609,10 @@ subroutine ex_coef ( & ! turb_length(k) is held, with Ri(k), on th-level(k-1) !--------------------------------------------------------- turb_length_layer = z_uv(i,j,kt) - z_uv(i,j,kb-1) - if (l_use_var_fixes) then - do kl = kb, kt - turb_length(i,j,kl) = max( turb_length(i,j,kl), & - min(turb_length_layer,lambda_max_nml*rlambda_fac) ) - end do - else - do kl = kb, kt - turb_length(i,j,kl) = max( lambda_min*rlambda_fac, & - min(turb_length_layer,lambda_max_nml*rlambda_fac) ) - end do - end if + do kl = kb, kt + turb_length(i,j,kl) = max( turb_length(i,j,kl), & + min(turb_length_layer,lambda_max_nml*rlambda_fac) ) + end do end if end do @@ -851,94 +647,255 @@ subroutine ex_coef ( & !$OMP end PARALLEL do end if !----------------------------------------------------------------------- -! 2. Richardson Number based local mixing scheme -!----------------------------------------------------------------------- -! 2.0 Loop round "boundary" levels; calculate the stability- -! dependent turbulent mixing coefficients. +! 2.0 Loop over levels; calculate the mixing lengths !----------------------------------------------------------------------- -! TKE budget based depth diagnosis +do k = 2, bl_levels +!$OMP PARALLEL DEFAULT(none) & +!$OMP PRIVATE(z_scale,j,i,lambdam,lambdah, & +!$OMP lambdah_rho,vkz,f_log,zz,zht,zfa,beta) & +!$OMP SHARED(k,pdims,ri,ricrit,flandg,ntml_local,ntml_nl,z_tq, & +!$OMP l_rp2,lambda_min,par_mezcla_rp,zh_local,turb_length,k_log_layr, & +!$OMP z_uv,z0m,elm,elh,elh_rho,blending_option,cumulus,l_shallow_cth,zhpar, & +!$OMP ntdsc,weight_1dbl,weight_bltop,delta_smag,rneutml_sq,BL_diag,local_fa) + !----------------------------------------------------------------- + ! 2.1 Calculate asymptotic mixing lengths LAMBDAM and LAMBDAH + !----------------------------------------------------------------- +!$OMP do SCHEDULE(STATIC) + do j = pdims%j_start, pdims%j_end + do i = pdims%i_start, pdims%i_end + if (l_rp2) then + lambdam = max ( lambda_min , par_mezcla_rp(rp_idx)*zh_local(i,j) ) + else + lambdam = max ( lambda_min , lambda_fac*zh_local(i,j) ) + end if + !----------------------------------------------------------------- + ! Reduce mixing lengths above BL + !----------------------------------------------------------------- + if (k >= ntml_local(i,j)+2) then + lambdam = lambda_min + end if -! Starting with the definition of the flux Richardson -! number, assuming similarity profiles for -! stress and buoyancy flux, and vertically integrating -! gives an expression for the stable boundary layer -! depth which is based just on surface fluxes and -! the wind speed change across the boundary layer. -! ---------------------------------------------------- + lambdah = lambdam + lambdah_rho = lambdah -if (sbl_op == depth_based) then + if ( local_fa == free_trop_layers ) then + lambdam = max( lambdam, lambda_fac*turb_length(i,j,k) ) + lambdah = max( lambdah, lambda_fac*turb_length(i,j,k) ) + ! lambdah_rho does not need to be recalculated under + ! local_fa option "free_trop_layers" as the full KH profile + ! will be interpolated in bdy_expl2 + end if + !----------------------------------------------------------------------- + ! 2.2 Calculate mixing lengths ELH, ELM coincident with RI(K) and so + ! at Z_TQ(K-1) + !----------------------------------------------------------------------- + ! Incorporate log profile corrections to the vertical finite + ! differences into the definitions of ELM and ELH. + ! Note that ELH_RHO is calculated (on rho levels) for direct inclusion + ! in RHOKH and also (as elh) on theta levels for the unstable + ! stability functions and inclusion in RHOKH before interpolation + ! (under local_fa option "free_trop_layers"). + ! To save computing logarithms for all K, the values of ELM and ELH + ! are unchanged for K > K_LOG_LAYR. - ! Index for assumed buoyancy profile - m_buoy=one + if (k <= k_log_layr) then + vkz = vkman * ( z_uv(i,j,k) - z_uv(i,j,k-1) ) + f_log = log( ( z_uv(i,j,k) + z0m(i,j) ) / & + ( z_uv(i,j,k-1) + z0m(i,j) ) ) + elm(i,j,k) = vkz / ( f_log + vkz/lambdam ) + elh(i,j,k) = vkz / ( f_log + vkz/lambdah ) + vkz = vkman * ( z_tq(i,j,k) - z_tq(i,j,k-1) ) + f_log = log( ( z_tq(i,j,k) + z0m(i,j) ) / & + ( z_tq(i,j,k-1) + z0m(i,j) ) ) + elh_rho(i,j,k) = vkz / ( f_log + vkz/lambdah_rho ) + else + vkz = vkman * ( z_tq(i,j,k-1) + z0m(i,j) ) + elm(i,j,k) = vkz / (one + vkz/lambdam ) + elh(i,j,k) = vkz / (one + vkz/lambdah ) + vkz = vkman * ( z_uv(i,j,k) + z0m(i,j) ) + elh_rho(i,j,k) = vkz / (one + vkz/lambdah_rho ) + end if + end do + end do +!$OMP end do +!---------------------------------------------------------------- +! 2.3 Blend mixing lengths between 1D and 3D Smagorinsky +!---------------------------------------------------------------- + if (blending_option /= off) then +!$OMP do SCHEDULE(STATIC) + do j = pdims%j_start, pdims%j_end + do i = pdims%i_start, pdims%i_end - ! Index for assumed stress profile - m_tau=one + zz = z_tq(i,j,k-1) ! height of rhokm(k) + ! turb_length is the greater of the local and non-local + ! BL depths up to that bl top + z_scale = max( zz, turb_length(i,j,k) ) + ! zht = interface between BL and FA + zht = max( z_uv(i,j,ntml_nl(i,j)+1) , zh_local(i,j) ) + ! Relevant scale in cumulus layers can be cloud top height, zhpar + if ( cumulus(i,j) .and. ( blending_option /= blend_cth_shcu_only .or. & + l_shallow_cth(i,j) ) ) then + z_scale = max( z_scale, zhpar(i,j) ) + zht = max( zht, zhpar(i,j) ) + end if + ! BL top includes decoupled stratocu layer, if it exists + if (ntdsc(i,j) > 0) zht = max( zht, z_uv(i,j,ntdsc(i,j)+1) ) + ! Need to restrict z_scale to dsc depth within a dsc layer + ! (given by turb_length) and to distance from dsc top below the + ! dsc layer + if ( k-1 <= ntdsc(i,j) ) then + z_scale = min( z_scale, & + max( turb_length(i,j,k), z_uv(i,j,ntdsc(i,j)+1)-zz ) ) + end if - ! Effective bulk flux Richardson number - rifb=0.3_r_bl + ! Finally calculate 1D BL weighting factor + if ( blending_option == blend_except_cu .and. & + cumulus(i,j) .and. ntdsc(i,j) == 0) then + ! pure cumulus layer so revert to 1D BL scheme + weight_1dbl(i,j,k) = one + else - ind=m_buoy-m_tau+one + if ( blending_option == blend_gridindep_fa .or. & + blending_option == blend_cth_shcu_only ) then + if (zz <= zht) then + weight_1dbl(i,j,k) = & + one - tanh( beta_bl*z_scale/delta_smag(i,j)) * & + max( zero, & + min( one, (linear0-delta_smag(i,j)/z_scale)*rlinfac) ) + weight_bltop(i,j) = weight_1dbl(i,j,k) + else ! above PBL + ! Above the PBL top (at zht) increase weight to one smoothly + ! between zht and zfa in order to default to 1D BL when not + ! turbulent. There is some arbitrariness here but: + ! a) we want to use a physical height, to avoid grid dependence + ! b) for shallow PBLs at high resolution it seems sensible to + ! get well (a PBL depth) above the resolved PBL before + ! reverting to 1D + ! c) for deep PBLs we still want to revert to 1D reasonably + ! quickly, hence within at most 1km of zht + zfa=min( 2.0_r_bl*zht, zht+1000.0_r_bl ) + if (zz <= zfa ) then + weight_1dbl(i,j,k) = one + one_half * & + (weight_bltop(i,j) - one) * & + ( one + cos(pi*(zz-zht)/(zfa-zht)) ) + else + weight_1dbl(i,j,k) = one + end if + if ( local_fa == free_trop_layers .and. & + ri(i,j,k) < ricrit(i,j) ) then + ! Except in an elevated turbulent layer where we still use + ! the standard blending weight + z_scale = turb_length(i,j,k) + weight_1dbl(i,j,k) = & + one - tanh( beta_bl*z_scale/delta_smag(i,j)) * & + max( zero, & + min( one, (linear0-delta_smag(i,j)/z_scale)*rlinfac) ) + end if + end if ! test on zz < zht + else + zfa=zht+1000.0_r_bl + if (zz <= zht) then + beta=beta_bl + else if (zz <= zfa) then + beta = beta_bl*(zfa-zz)/(zfa-zht) + & + beta_fa*(zz-zht)/(zfa-zht) + else + beta=beta_fa + end if + weight_1dbl(i,j,k) = & + one - tanh( beta*z_scale/delta_smag(i,j)) * max( zero, & + min( one, (linear0-delta_smag(i,j)/z_scale)*rlinfac) ) + end if + end if + + elm(i,j,k) = elm(i,j,k)*weight_1dbl(i,j,k) + & + sqrt(rneutml_sq(i,j,k-1))*(one-weight_1dbl(i,j,k)) + elh(i,j,k) = elh(i,j,k)*weight_1dbl(i,j,k) + & + sqrt(rneutml_sq(i,j,k-1))*(one-weight_1dbl(i,j,k)) + end do + end do +!$OMP end do + end if ! test on blending_option +!$OMP end PARALLEL +end do ! loop over levels +!---------------------------------------------------------------- +! 3.0 Calculate stability functions +!---------------------------------------------------------------- +! 3.1 Set-up a BL weighting function, =1 near the ground (ie in the BL) +! =0 in the free troposphere +! Rate and height at which transition occurs varys depending on choices +!----------------------------------------------------------------------- +!$OMP PARALLEL DEFAULT(none) private( i, j, k, z_scale, zpr) & +!$OMP SHARED( pdims, bl_levels, BL_weight, local_fa, z_tq, sg_orog_mixing, & +!$OMP sigma_h) +!$OMP do SCHEDULE(STATIC) +do k = 1, bl_levels do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end - - ! Set diff_min to a large initial value - diff_min(i,j)=1000.0_r_bl - - ! Surface Obukhov length - MOsurf(i,j)= -v_s(i,j)*v_s(i,j)*v_s(i,j) & - /(vkman*fb_surf(i,j)) + BL_weight(i,j,k) = one end do end do +end do +!$OMP end do +if (local_fa == to_sharp_across_1km) then + !--------------------------------------------------------- + ! Additional code to allow the local Ri scheme to use + ! SHARPEST in the free atmosphere, ie above the BL top, + ! regardless of the tail option selected above. + ! Set Z_SCALE to 1km to mimic old value of BL_LEVELS, + ! gives BL_weight~0 by 2km, ~0.95 at 500m + !--------------------------------------------------------- + z_scale = 1000.0_r_bl +!$OMP do SCHEDULE(STATIC) do k = 2, bl_levels do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end + zpr = z_tq(i,j,k-1)/z_scale + BL_weight(i,j,k) = one_half*(one - tanh(3.0_r_bl*(zpr-one) ) ) + end do + end do + end do +!$OMP end do NOWAIT +end if - ! The wind speed change from level k to the surface - u1=sqrt(u_p(i,j,k)*u_p(i,j,k)+v_p(i,j,k)*v_p(i,j,k)) - - ! h_est is the estimate of the stable boundary layer - ! depth using the TKE based formula - h_est=vkman*MOsurf(i,j)*ind*rifb*u1/v_s(i,j) - - ! Absolute difference between height and estimate - diff=abs(z_uv(i,j,k)-h_est) - - ! If h_est is closer than the previous closest value - ! (diff_min) reset the h_tkeb to h_est - - if (diff < diff_min(i,j)) then - diff_min(i,j)=diff - h_tkeb(i,j)=h_est +if (sg_orog_mixing /= off) then + !----------------------------------------------------------------- + ! Subgrid orographic height dependence for SBL tail (option 1) + ! or orographic dependence of mixing lengths, lambdam,h (opt 2) + ! Gives BL_weight~[1,0.95,0.5,0] at ZPR=[0,0.6,1,1.7] + !---------------------------------------------------------------- +!$OMP do SCHEDULE(STATIC) + do k = 2, bl_levels + do j = pdims%j_start, pdims%j_end + do i = pdims%i_start, pdims%i_end + if (sigma_h(i,j) > one ) then + zpr = z_tq(i,j,k-1)/sigma_h(i,j) + BL_weight(i,j,k) = one_half*( one - tanh(4.0_r_bl*(zpr-one) ) ) end if - end do end do end do - -end if ! SBL_OP = Depth_based - +!$OMP end do NOWAIT +end if +!$OMP end PARALLEL ! ---------------------------------------------------------------- -! Main loop over levels +! 3.2 calculating stable stability function +! ---------------------------------------------------------------- +! Load up 2D array FUNC with selected stability function for Ri>=0 +! +! SBL_OP Option +! +! Long_tails Long tails +! Sharpest SHARPEST function +! Sharp_sea_long_land SHARPEST over sea ; Long tails over land +! Mes_tails MESOSCALE model: Louis/SHARPEST blend +! Louis_tails Louis function +! Sharp_sea_mes_land SHARP over sea; Mes over land +! Sharp_sea_Louis_land SHARP over sea; Louis over land ! ---------------------------------------------------------------- - do k = 2, bl_levels - ! ---------------------------------------------------------------- - ! Load up 2D array FUNC with selected stability function for Ri>=0 - - ! SBL_OP Option - - ! Long_tails Long tails - ! Sharpest SHARPEST function - ! Sharp_sea_long_land SHARPEST over sea ; Long tails over land - ! Mes_tails MESOSCALE model: Louis/SHARPEST blend - ! Louis_tails Louis function - ! Depth_based Boundary layer depth based formulation - ! Sharp_sea_mes_land SHARP over sea; Mes over land - ! Sharp_sea_Louis_land SHARP over sea; Louis over land - ! ---------------------------------------------------------------- - select case (sbl_op) !-------------------------------------------- @@ -1061,19 +1018,6 @@ subroutine ex_coef ( & end do end do - !-------------------------------------------- - ! long TAILS FOR use WITH DEPTH BASED SCHEME - !-------------------------------------------- - case (depth_based) - ! long TAILS - do j = pdims%j_start, pdims%j_end - do i = pdims%i_start, pdims%i_end - if (ri(i,j,k) >= zero) then - func(i,j)=one / ( one + g0 * ri(i,j,k) ) - end if - end do - end do - !-------------------------------------------- ! SHARP TAILS OVER SEA; MES TAILS OVER LAND !-------------------------------------------- @@ -1152,9 +1096,8 @@ subroutine ex_coef ( & end select ! SBL_OP !------------------------------------------------------------------ - ! Additional code to allow the local Ri scheme to use - ! SHARPEST in the free atmosphere, ie above the BL top, - ! regardless of the tail option selected above. + ! Additional option to use SHARPEST in the free atmosphere, ie above + ! the BL top, regardless of the tail option selected above. !------------------------------------------------------------------ if (local_fa == to_sharp_across_1km) then @@ -1214,7 +1157,7 @@ subroutine ex_coef ( & end if !--------------------------------------------------------------- - ! Set stable Prandtl number (=KM/KH) + ! 3.3 Set stable Prandtl number (=KM/KH) !--------------------------------------------------------------- if (sbl_op == lem_stability) then !$OMP PARALLEL do DEFAULT(none) SCHEDULE(STATIC) & @@ -1244,223 +1187,20 @@ subroutine ex_coef ( & end do !$OMP end PARALLEL do end if - -!$OMP PARALLEL do SCHEDULE(STATIC) DEFAULT(none) & -!$OMP private(z_scale,fm,j,i,lambdam,lambdah,lambda_eff, & -!$OMP lambdah_rho,vkz,f_log,zz,zht,zfa,beta,fh,rtmri,km,rpr) & -!$OMP SHARED(k,sbl_op,var_diags_opt,bl_levels,pdims,g0,ri,ricrit, & -!$OMP flandg,ntml_local,ntml_nl,subb,dh,z_tq, & -!$OMP BL_weight,sg_orog_mixing,sigma_h,pr_n, & -!$OMP l_rp2,lambda_min,par_mezcla_rp,zh_local, & -!$OMP h_blend,turb_length,k_log_layr, & -!$OMP z_uv,z0m,elm,elh,elh_rho,blending_option,cumulus,l_shallow_cth,zhpar, & -!$OMP ntdsc,weight_1dbl,weight_bltop,delta_smag,rneutml_sq,BL_diag, & -!$OMP r_pr_n,cbl_op,subc,dm,h_tkeb,v_s,MOsurf,rho_wet_tq, & -!$OMP l_subfilter_vert,l_subfilter_horiz,fm_3d,fh_3d,rhokm,tke_loc, & -!$OMP dvdzm,l_mr_physics,rhokh,local_fa,fb_surf,func,prandtl_number) - do j = pdims%j_start, pdims%j_end +!---------------------------------------------------------------- +! 3.4 Calculate (values of) stability functions FH, FM. +!---------------------------------------------------------------- +!$OMP PARALLEL DEFAULT(none) & +!$OMP SHARED( k, pdims,BL_diag,elm,elh,ri,func,prandtl_number,cbl_op,r_pr_n, & +!$OMP l_subfilter_vert,l_subfilter_horiz,fm_3d,fh_3d,rhokm,rhokh, & +!$OMP rho_wet_tq,dvdzm,l_mr_physics,local_fa,tke_loc,subb,subc,g0,dm, & +!$OMP dh ) & +!$OMP PRIVATE( i, j, fm, fh, rtmri, rpr ) +!$OMP do SCHEDULE(STATIC) + do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end - !----------------------------------------------------------------- - ! 2.1 Calculate asymptotic mixing lengths LAMBDAM and LAMBDAH - ! (may be equal or LambdaM=2*LambdaH (operational setting)). - !----------------------------------------------------------------- - if (l_lambdam2) then - if (l_rp2) then - lambdam = max (lambda_min , 2*par_mezcla_rp(rp_idx)*zh_local(i,j)) - lambdah = max (lambda_min , par_mezcla_rp(rp_idx)*zh_local(i,j)) - else - lambdam = max (lambda_min , 0.30_r_bl*zh_local(i,j)) - lambdah = max (lambda_min , 0.15_r_bl*zh_local(i,j)) - end if - else - if (l_rp2) then - lambdam = max ( lambda_min , par_mezcla_rp(rp_idx)*zh_local(i,j) ) - else - lambdam = max ( lambda_min , lambda_fac*zh_local(i,j) ) - end if - lambdah = lambdam - end if - - if (sg_orog_mixing == sg_shear_enh_lambda) then - !-------------------------------------------------------------- - ! Use orographic mixing length for heat too, and reduce both - ! above sigma_h smoothly - ! NOTE: THIS CODE WILL not ENHANCE LAMBDAH because it only - ! gets used in bdy_expl2 where the calculation is redone as - ! standard - this was a mistake but is now operational in - ! the UKV! - !-------------------------------------------------------------- - if (k >= ntml_local(i,j)+2) then - lambdam = lambda_min - lambdah = lambda_min - end if - lambdah = max (lambdah, & - BL_weight(i,j,k)*a_lambda*h_blend(i,j) ) - lambda_eff = max (lambdam, & - BL_weight(i,j,k)*a_lambda*h_blend(i,j) ) - else - lambda_eff = max (lambdam, a_lambda*h_blend(i,j) ) - !------------------------------------------------------------ - ! Optionally reduce mixing length above local BL top - !------------------------------------------------------------ - if (k >= ntml_local(i,j)+2 .and. .not. l_full_lambdas) then - lambdam = lambda_min - lambdah = lambda_min - if (z_tq(i,j,k-1) > a_lambda*h_blend(i,j)) & - lambda_eff=lambda_min - end if - if ( k >= ntml_local(i,j)+2 .and. l_full_lambdas .and. & - local_fa == to_sharp_across_1km ) then - ! Weight lambda to lambda_min with height - ! Assuming only local_fa == to_sharp_across_1km will have - ! L_FULL_LAMBDAS. If other LOCAL_FA options are coded here - ! then changes must be included in section 5.3 of bdy_expl2 - - lambda_eff = lambda_eff * BL_weight(i,j,k) & - + lambda_min*( one - BL_weight(i,j,k) ) - lambdah = lambdah * BL_weight(i,j,k) & - + lambda_min*( one - BL_weight(i,j,k) ) - end if - end if - - lambdah_rho = lambdah - - if ( local_fa == free_trop_layers ) then - lambda_eff = max( lambda_eff, lambda_fac*turb_length(i,j,k) ) - lambdah = max( lambdah, lambda_fac*turb_length(i,j,k) ) - ! lambdah_rho does not need to be recalculated under - ! local_fa option "free_trop_layers" as the full KH profile - ! will be interpolated in bdy_expl2 - end if - !----------------------------------------------------------------------- - ! 2.2 Calculate mixing lengths ELH, ELM coincident with RI(K) and so - ! at Z_TQ(K-1) - !----------------------------------------------------------------------- - ! Incorporate log profile corrections to the vertical finite - ! differences into the definitions of ELM and ELH. - ! Note that ELH_RHO is calculated (on rho levels) for direct inclusion - ! in RHOKH and also (as elh) on theta levels for the unstable - ! stability functions and inclusion in RHOKH before interpolation - ! (under local_fa option "free_trop_layers"). - ! To save computing logarithms for all K, the values of ELM and ELH - ! are unchanged for K > K_LOG_LAYR. - - if (k <= k_log_layr) then - vkz = vkman * ( z_uv(i,j,k) - z_uv(i,j,k-1) ) - f_log = log( ( z_uv(i,j,k) + z0m(i,j) ) / & - ( z_uv(i,j,k-1) + z0m(i,j) ) ) - elm(i,j,k) = vkz / ( f_log + vkz/lambda_eff ) - elh(i,j,k) = vkz / ( f_log + vkz/lambdah ) - vkz = vkman * ( z_tq(i,j,k) - z_tq(i,j,k-1) ) - f_log = log( ( z_tq(i,j,k) + z0m(i,j) ) / & - ( z_tq(i,j,k-1) + z0m(i,j) ) ) - elh_rho(i,j,k) = vkz / ( f_log + vkz/lambdah_rho ) - else - vkz = vkman * ( z_tq(i,j,k-1) + z0m(i,j) ) - elm(i,j,k) = vkz / (one + vkz/lambda_eff ) - elh(i,j,k) = vkz / (one + vkz/lambdah ) - vkz = vkman * ( z_uv(i,j,k) + z0m(i,j) ) - elh_rho(i,j,k) = vkz / (one + vkz/lambdah_rho ) - end if - - if (blending_option /= off) then - - zz = z_tq(i,j,k-1) ! height of rhokm(k) - ! turb_length is the greater of the local and non-local - ! BL depths up to that bl top - z_scale = max( zz, turb_length(i,j,k) ) - ! zht = interface between BL and FA - zht = max( z_uv(i,j,ntml_nl(i,j)+1) , zh_local(i,j) ) - ! Relevant scale in cumulus layers can be cloud top height, zhpar - if ( cumulus(i,j) .and. ( blending_option /= blend_cth_shcu_only .or. & - l_shallow_cth(i,j) ) ) then - z_scale = max( z_scale, zhpar(i,j) ) - zht = max( zht, zhpar(i,j) ) - end if - ! BL top includes decoupled stratocu layer, if it exists - if (ntdsc(i,j) > 0) zht = max( zht, z_uv(i,j,ntdsc(i,j)+1) ) - ! Need to restrict z_scale to dsc depth within a dsc layer - ! (given by turb_length) and to distance from dsc top below the - ! dsc layer - if ( k-1 <= ntdsc(i,j) ) then - z_scale = min( z_scale, & - max( turb_length(i,j,k), z_uv(i,j,ntdsc(i,j)+1)-zz ) ) - end if - - ! Finally calculate 1D BL weighting factor - if ( blending_option == blend_except_cu .and. & - cumulus(i,j) .and. ntdsc(i,j) == 0) then - ! pure cumulus layer so revert to 1D BL scheme - weight_1dbl(i,j,k) = one - else - - if ( blending_option == blend_gridindep_fa .or. & - blending_option == blend_cth_shcu_only ) then - if (zz <= zht) then - weight_1dbl(i,j,k) = & - one - tanh( beta_bl*z_scale/delta_smag(i,j)) * & - max( zero, & - min( one, (linear0-delta_smag(i,j)/z_scale)*rlinfac) ) - weight_bltop(i,j) = weight_1dbl(i,j,k) - else ! above PBL - ! Above the PBL top (at zht) increase weight to one smoothly - ! between zht and zfa in order to default to 1D BL when not - ! turbulent. There is some arbitrariness here but: - ! a) we want to use a physical height, to avoid grid dependence - ! b) for shallow PBLs at high resolution it seems sensible to - ! get well (a PBL depth) above the resolved PBL before - ! reverting to 1D - ! c) for deep PBLs we still want to revert to 1D reasonably - ! quickly, hence within at most 1km of zht - zfa=min( 2.0_r_bl*zht, zht+1000.0_r_bl ) - if (zz <= zfa ) then - weight_1dbl(i,j,k) = one + one_half * & - (weight_bltop(i,j) - one) * & - ( one + cos(pi*(zz-zht)/(zfa-zht)) ) - else - weight_1dbl(i,j,k) = one - end if - if ( local_fa == free_trop_layers .and. & - ri(i,j,k) < ricrit(i,j) ) then - ! Except in an elevated turbulent layer where we still use - ! the standard blending weight - z_scale = turb_length(i,j,k) - weight_1dbl(i,j,k) = & - one - tanh( beta_bl*z_scale/delta_smag(i,j)) * & - max( zero, & - min( one, (linear0-delta_smag(i,j)/z_scale)*rlinfac) ) - - end if - end if ! test on zz < zht - else - zfa=zht+1000.0_r_bl - if (zz <= zht) then - beta=beta_bl - else if (zz <= zfa) then - beta = beta_bl*(zfa-zz)/(zfa-zht) + & - beta_fa*(zz-zht)/(zfa-zht) - else - beta=beta_fa - end if - weight_1dbl(i,j,k) = & - one - tanh( beta*z_scale/delta_smag(i,j)) * max( zero, & - min( one, (linear0-delta_smag(i,j)/z_scale)*rlinfac) ) - end if - end if - - elm(i,j,k) = elm(i,j,k)*weight_1dbl(i,j,k) + & - sqrt(rneutml_sq(i,j,k-1))*(one-weight_1dbl(i,j,k)) - elh(i,j,k) = elh(i,j,k)*weight_1dbl(i,j,k) + & - sqrt(rneutml_sq(i,j,k-1))*(one-weight_1dbl(i,j,k)) - - end if ! test on blending_option if (BL_diag%l_elm3d) BL_diag%elm3d(i,j,k)=elm(i,j,k) - - !---------------------------------------------------------------- - ! 2.4 Calculate (values of) stability functions FH, FM. - !---------------------------------------------------------------- - if (ri(i,j,k) >= zero) then !----------------------------------------------------------- ! Note that we choose to include the Pr dependence such that @@ -1489,7 +1229,7 @@ subroutine ex_coef ( & end if !------------------------------------------------------------------ - ! 2.5_r_bl Calculate exchange coefficients RHO*KM(K), RHO*KH(K) + ! 4.0 Calculate exchange coefficients RHO*KM(K), RHO*KH(K) ! both on TH-level K-1 at this stage (RHOKH will be interpolated ! onto uv-levels and then be multiplied by ELH in BDY_EXPL2 if ! local_fa is not "free_trop_layers") @@ -1517,7 +1257,7 @@ subroutine ex_coef ( & if (local_fa == free_trop_layers) & rhokh(i,j,k) = rhokh(i,j,k) * elh(i,j,k) - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then rpr = fh / max(fm, tiny(one) ) tke_loc(i,j,k) = ( r_c_tke*elm(i,j,k)*dvdzm(i,j,k)*dvdzm(i,j,k) & *(rhokm(i,j,k)/rho_wet_tq(i,j,k-1)) & @@ -1525,47 +1265,13 @@ subroutine ex_coef ( & one - ri(i,j,k)*rpr ) ) & )**two_thirds end if - ! ------------------------------------------- - ! Boundary layer depth based formulation - ! ------------------------------------------- - - if (sbl_op == depth_based .and. & - fb_surf(i,j) <= zero) then - if (z_tq(i,j,k-1) < h_tkeb(i,j)) then - - ! Formula for diffusion coefficient - ! see Beare et al 2006, Boundary layer Met. - - km = v_s(i,j) * vkman * z_tq(i,j,k-1) * & - ( (one-z_tq(i,j,k-1)/h_tkeb(i,j))**(1.5_r_bl) ) & - / (one + 4.7_r_bl*z_tq(i,j,k-1)/MOsurf(i,j)) - rhokm(i,j,k)= rho_wet_tq(i,j,k-1) * km - if (l_mr_physics) then - ! Note "RHO" here is always wet density (RHO_WET_TQ) so - ! save multiplication of RHOKH to after interpolation - rhokh(i,j,k)= km*r_pr_n / elm(i,j,k) - else - rhokh(i,j,k) = rho_wet_tq(i,j,k-1)*km*r_pr_n /elm(i,j,k) - end if - else - rhokm(i,j,k)=zero - rhokh(i,j,k)=zero - end if - end if !SBL_OP == Depth_based - - end do !I + end do !i end do !j -!$OMP end PARALLEL do +!$OMP end do +!$OMP end PARALLEL end do ! bl_levels -!----------------------------------------------------------------------- -! 3. Equilibrium Stable Boundary Layer (SBL) model. -!----------------------------------------------------------------------- -!----------------------------------------------------------------------- -! Finish up -!----------------------------------------------------------------------- - if (lhook) call dr_hook(ModuleName//':'//RoutineName,zhook_out,zhook_handle) return end subroutine ex_coef diff --git a/science/physics_schemes/source/boundary_layer/excf_nl_9c.F90 b/science/physics_schemes/source/boundary_layer/excf_nl_9c.F90 index 4525be05d..a708083c2 100644 --- a/science/physics_schemes/source/boundary_layer/excf_nl_9c.F90 +++ b/science/physics_schemes/source/boundary_layer/excf_nl_9c.F90 @@ -56,7 +56,7 @@ subroutine excf_nl_9c ( & flux_grad, Locketal2000, HoltBov1993, LockWhelan2006, entr_smooth_dec, & entr_taper_zh, kprof_cu, klcl_entr, buoy_integ, buoy_integ_low, & max_cu_depth, bl_res_inv, a_ent_shr_nml, a_ent_2, one_third, two_thirds, & - l_reset_dec_thres, var_diags_opt, original_vars, split_tke_and_inv, & + l_reset_dec_thres, & l_use_var_fixes, dzrad_disc_opt, dzrad_ntm1, dzrad_1p5dz, & num_sweeps_bflux, l_converge_ga, l_use_sml_dsc_fixes, zero, one, one_half use model_domain_mod, only: model_type, mt_single_column @@ -2990,7 +2990,7 @@ subroutine excf_nl_9c ( & ( (max(one - km_sct_factor(i,j)*z_pr/zh_pr, zero))**0.8_r_bl ) & * z_pr * z_pr / zh_pr ! PRANDTL=0.75 - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then ! save Km/timescale for TKE diag, completed in bdy_expl2 tke_nl(i,j,k)=rhokm_top(i,j,k)*c_tke*v_top(i,j)/zh(i,j) end if @@ -3054,26 +3054,13 @@ subroutine excf_nl_9c ( & 0.75_r_bl*rho_wet_tq(i,j,k-1)*v_top_dsc(i,j)*g1*vkman* & ( (max(one - km_dsct_factor(i,j)*z_pr/zh_pr,zero))**0.8_r_bl ) & * z_pr * z_pr / zh_pr - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then ! save Km/timescale for TKE diag, completed in bdy_expl2 tke_nl(i,j,k) = tke_nl(i,j,k) + & rhokm_dsct*c_tke*v_top_dsc(i,j)/dscdepth(i,j) end if rhokm_top(i,j,k) = rhokm_top(i,j,k) + rhokm_dsct end if - if (BL_diag%l_tke .and. var_diags_opt == original_vars) then - ! save 1/timescale for TKE diag, completed in bdy_expl2 - if ( zk_tq < zsml_top(i,j) .and. & - zk_tq > zsml_base(i,j) ) then - BL_diag%tke(i,j,k) = c_tke*v_top(i,j)/zh(i,j) - end if - if ( zk_tq < zhsc(i,j) .and. & - zk_tq > zdsc_base(i,j) ) then - ! save 1/timescale for TKE diag, completed in bdy_expl2 - BL_diag%tke(i,j,k) = max( BL_diag%tke(i,j,k), & - c_tke*v_top_dsc(i,j)/dscdepth(i,j) ) - end if - end if end do end do @@ -3183,19 +3170,12 @@ subroutine excf_nl_9c ( & ( one - ( zk_tq / zh(i,j) ) ) * & ( one - ( zk_tq / zh(i,j) ) ) - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then ! save Km/timescale for TKE diag, completed in bdy_expl2 tke_nl(i,j,k) = tke_nl(i,j,k) + & rhokm(i,j,k)*c_tke*w_m_tq/zh(i,j) end if end if - if (BL_diag%l_tke .and. var_diags_opt == original_vars) then - ! save 1/timescale for TKE diag, completed in bdy_expl2 - if ( zk_tq < zsml_top(i,j) ) then - BL_diag%tke(i,j,k) = max( BL_diag%tke(i,j,k), & - c_tke*w_m_tq/zh(i,j) ) - end if - end if end if end do end do @@ -3333,7 +3313,7 @@ subroutine excf_nl_9c ( & ( one - km_top_factor(i,j) * ( zk_tq / zh(i,j) ) ) * & ( one - km_top_factor(i,j) * ( zk_tq / zh(i,j) ) ) - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then ! save Km/timescale for TKE diag, completed in bdy_expl2 tke_nl(i,j,k) = tke_nl(i,j,k) + & rhokm(i,j,k)*c_tke*w_m_tq/zh(i,j) @@ -3345,20 +3325,13 @@ subroutine excf_nl_9c ( & rhokm(i,j,k) = prandtl_top(i,j) * rhokh_lcl(i,j) * & exp(-(zk_tq-zh(i,j))/cu_depth_scale(i,j)) * & (one-(zk_tq-zh(i,j))/(zsml_top(i,j)-zh(i,j))) - if (BL_diag%l_tke .and. var_diags_opt==split_tke_and_inv) then + if (BL_diag%l_tke) then ! save Km/timescale for TKE diag, completed in bdy_expl2 tke_nl(i,j,k) = tke_nl(i,j,k) + & rhokm(i,j,k)*c_tke*w_m_tq/zh(i,j) end if end if end if - if (BL_diag%l_tke .and. var_diags_opt == original_vars) then - ! save 1/timescale for TKE diag, completed in bdy_expl2 - if ( zk_tq < zsml_top(i,j) ) then - BL_diag%tke(i,j,k) = max( BL_diag%tke(i,j,k), & - c_tke*w_m_tq/zh(i,j) ) - end if - end if end if end do diff --git a/science/physics_schemes/source/boundary_layer/imp_mix.F90 b/science/physics_schemes/source/boundary_layer/imp_mix.F90 index 622a181f4..3d5916f32 100644 --- a/science/physics_schemes/source/boundary_layer/imp_mix.F90 +++ b/science/physics_schemes/source/boundary_layer/imp_mix.F90 @@ -32,7 +32,7 @@ subroutine imp_mix ( & use atm_fields_bounds_mod, only: pdims, array_dims use yomhook, only: lhook, dr_hook use parkind1, only: jprb, jpim -!$ use omp_lib, only: omp_get_num_threads +!$ use omp_lib, only: omp_get_max_threads implicit none ! Inputs :- @@ -109,10 +109,13 @@ subroutine imp_mix ( & ! K minus 1. kp1, & ! K plus 1. - jj, & + ii, & ! omp blocking counter - omp_block + pdims_omp_block, & ! omp block size + pdims_seg_block, & + ! omp segment length + max_threads integer(kind=jpim), parameter :: zhook_in = 0 integer(kind=jpim), parameter :: zhook_out = 1 @@ -124,14 +127,15 @@ subroutine imp_mix ( & blm1 = bl_levels-1 -omp_block = pdims%j_len +max_threads = 1 +!$ max_threads = omp_get_max_threads() +pdims_omp_block = ceiling(real(pdims%i_end)/max_threads) +pdims_seg_block = min(pdims_omp_block, pdims%i_len) -!$OMP PARALLEL DEFAULT(none) SHARED(f_field, dtrdz, field, pdims, & +!$OMP PARALLEL DEFAULT(none) SHARED(pdims_seg_block, f_field, dtrdz, field, pdims, & !$OMP gamma_rhokh_rdz, r_rho_levels, surf_dep_flux, d_field, af, & !$OMP r_theta_levels, gamma_rhok_dep, bl_levels, blm1) & -!$OMP private(r_sq, cf, rbf, kp1, km1, jj, k, j, i, rr_sq, omp_block) - -!$ omp_block = ceiling(real(pdims%j_len)/ omp_get_num_threads()) +!$OMP private(r_sq, cf, rbf, kp1, km1, ii, k, j, i, rr_sq) ! ---------------------------------------------------------------------- ! (A) Calculations on P-grid. @@ -191,12 +195,12 @@ subroutine imp_mix ( & !----------------------------------------------------------------------- !$OMP do SCHEDULE(STATIC) -do jj = pdims%j_start, pdims%j_end, omp_block +do ii = pdims%i_start, pdims%i_end, pdims_seg_block do k = 2, blm1 kp1 = k+1 km1 = k-1 - do j = jj, min(jj+omp_block-1, pdims%j_end) - do i = pdims%i_start, pdims%i_end + do j = pdims%j_start, pdims%j_end + do i = ii, min(ii+pdims_seg_block-1, pdims%i_end) ! "Explicit" flux divergence across layer giving explicit FIELD ! increment due to mixing @@ -245,10 +249,10 @@ subroutine imp_mix ( & !----------------------------------------------------------------------- !$OMP do SCHEDULE(STATIC) -do jj = pdims%j_start, pdims%j_end, omp_block +do ii = pdims%i_start, pdims%i_end, pdims_seg_block do k = blm1, 1, -1 - do j = jj, min(jj+omp_block-1,pdims%j_end) - do i = pdims%i_start, pdims%i_end + do j = pdims%j_start, pdims%j_end + do i = ii, min(ii+pdims_seg_block-1,pdims%i_end) d_field(i,j,k) = d_field(i,j,k) - & af(i,j,k)*d_field(i,j,k+1) field(i,j,k) = field(i,j,k) + d_field(i,j,k) diff --git a/science/physics_schemes/source/boundary_layer/kmkhz_9c.F90 b/science/physics_schemes/source/boundary_layer/kmkhz_9c.F90 index 24008fac1..32fb1559c 100644 --- a/science/physics_schemes/source/boundary_layer/kmkhz_9c.F90 +++ b/science/physics_schemes/source/boundary_layer/kmkhz_9c.F90 @@ -57,8 +57,7 @@ subroutine kmkhz_9c ( & a_grad_adj, max_t_grad, flux_grad, Locketal2000, & HoltBov1993, LockWhelan2006, entr_smooth_dec, entr_taper_zh, & kprof_cu, l_use_sml_dsc_fixes, l_converge_ga, & - bl_res_inv, cosine_inv_flux, target_inv_profile, pr_max, var_diags_opt, & - split_tke_and_inv, l_noice_in_turb, & + bl_res_inv, cosine_inv_flux, target_inv_profile, pr_max, l_noice_in_turb, & one_third, two_thirds, zero, one, one_half use conversions_mod, only: pi => pi_bl use cv_run_mod, only: l_param_conv @@ -4165,7 +4164,7 @@ subroutine kmkhz_9c ( & if (res_inv(i,j) == 1) then Prandtl = min( rhokm(i,j,k)/(rbl_eps+rhokh_surf_ent(i,j)), & pr_max ) - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then ! need velocity scale for TKE diagnostic w_m = ( v_s(i,j)*v_s(i,j)*v_s(i,j) + & c_ws * zh(i,j) * fb_surf(i,j) ) ** one_third @@ -4189,7 +4188,7 @@ subroutine kmkhz_9c ( & * rdz(i,j,kl) * (z_uv(i,j,kl)-z_uv(i,j,kl-1)) & * rho_wet_tq(i,j,kl-1) / rho_mix(i,j,kl) rhokm(i,j,kl) = max( rhokm(i,j,kl), rhok_inv ) - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then ! save Km/timescale for TKE diag, completed in bdy_expl2 tke_nl(i,j,kl) = max( tke_nl(i,j,kl), rhok_inv*c_tke*w_m/zh(i,j)) end if @@ -4237,7 +4236,7 @@ subroutine kmkhz_9c ( & * rdz(i,j,kl) * (z_uv(i,j,kl)-z_uv(i,j,kl-1)) & * rho_wet_tq(i,j,kl-1) / rho_mix(i,j,kl) rhokm(i,j,kl) = max( rhokm(i,j,kl), rhok_inv ) - if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then + if (BL_diag%l_tke) then ! save Km/timescale for TKE diag, completed in bdy_expl2 tke_nl(i,j,kl) = max( tke_nl(i,j,kl), rhok_inv*c_tke*w_m/zh(i,j)) end if @@ -4702,7 +4701,7 @@ subroutine kmkhz_9c ( & ! Estimate turbulent w-variance scale at discontinuous inversions !----------------------------------------------------------------------- -if (BL_diag%l_tke .and. var_diags_opt == split_tke_and_inv) then +if (BL_diag%l_tke) then !$OMP do SCHEDULE(STATIC) do j = pdims%j_start, pdims%j_end do i = pdims%i_start, pdims%i_end diff --git a/science/physics_schemes/source/convection/glue_conv-6a.F90 b/science/physics_schemes/source/convection/glue_conv-6a.F90 index fdb28dabb..5b718e815 100644 --- a/science/physics_schemes/source/convection/glue_conv-6a.F90 +++ b/science/physics_schemes/source/convection/glue_conv-6a.F90 @@ -15,7 +15,7 @@ module glue_conv_6a_mod contains ! -subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & +subroutine glue_conv_6a(ncells,seg_size,nlev,n_wtrac,nbl, & call_number,seg_num & , th,q,qcl,qcf & , q_wtrac, qcl_wtrac, qcf_wtrac & @@ -153,27 +153,27 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! ! Arguments with intent in: ! -integer, intent(in) :: np_field ! No of points in a full field +integer, intent(in) :: ncells ! No of points in a full field !(note all multi-dimensional fields ! passed to routine MUST be -! dimensioned with np_field) +! dimensioned with ncells) -integer, intent(in) :: npnts ! No. of points in segment +integer, intent(in) :: seg_size ! No. of points in segment -! NOTE - loops over points should be over npnts or less NEVER over np_field. +! NOTE - loops over points should be over seg_size or less NEVER over ncells. integer, intent(in) :: nlev ! No. of model layers used in convection integer, intent(in) :: n_wtrac ! No. of water tracers, ! set to 1 if l_wtrac_conv=F -integer, intent(in) :: ntml(npnts) ! Top level of surface mixed +integer, intent(in) :: ntml(seg_size) ! Top level of surface mixed ! layer defined relative to ! theta,q grid -integer, intent(in) :: ntpar(npnts) ! Top level of initial parcel +integer, intent(in) :: ntpar(seg_size) ! Top level of initial parcel ! ascent in BL scheme defined ! relative to theta,q grid -integer, intent(in) :: conv_type(npnts) +integer, intent(in) :: conv_type(seg_size) ! Integer index describing convective type: ! 0=no convection ! 1=non-precipitating shallow @@ -205,154 +205,154 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & integer, intent(in) :: n_md ! Number of mid points -real(kind=real_umphys), intent(in) :: delthvu_bl(npnts) +real(kind=real_umphys), intent(in) :: delthvu_bl(seg_size) !Integral of undilute parcel ! buoyancy over convective cloud ! layer (Kelvin m) real(kind=real_umphys), intent(in) :: & - ql_ad(npnts) & ! adiabatic liquid water content at inversion (kg/kg) - , qsat_lcl(npnts) & ! qsat at cloud base (kg/kg) - , ftl(npnts) & ! Surface sensible heat flux divided by cp from BL + ql_ad(seg_size) & ! adiabatic liquid water content at inversion (kg/kg) + , qsat_lcl(seg_size) & ! qsat at cloud base (kg/kg) + , ftl(seg_size) & ! Surface sensible heat flux divided by cp from BL ! (K kg/m2/s) i.e. rho*w'tl' - , fqt(npnts) & ! Total water flux from surface (kg/m2/s) + , fqt(seg_size) & ! Total water flux from surface (kg/m2/s) ! i.e. rho*w'qT' - , delta_smag(npnts) ! grid size used in smagorinsky length scale (m) + , delta_smag(seg_size) ! grid size used in smagorinsky length scale (m) -real(kind=real_umphys), intent(in) :: r_rho(np_field,nlev) +real(kind=real_umphys), intent(in) :: r_rho(ncells,nlev) ! radius rho levels(m) -real(kind=real_umphys), intent(in) :: r_theta(np_field,0:nlev) +real(kind=real_umphys), intent(in) :: r_theta(ncells,0:nlev) ! theta levels (m) real(kind=real_umphys), intent(in) :: & - rho(np_field,nlev) & ! Wet density on rho levels (kg/m3) - ,rho_theta(np_field,nlev) & ! Wet denisty on theta levels (kg/m3) - ,rho_dry(np_field,nlev) & ! dry density on rho levels (kg/m3) - ,rho_dry_theta(np_field,nlev) ! dry density on theta levels (kg/m3) + rho(ncells,nlev) & ! Wet density on rho levels (kg/m3) + ,rho_theta(ncells,nlev) & ! Wet denisty on theta levels (kg/m3) + ,rho_dry(ncells,nlev) & ! dry density on rho levels (kg/m3) + ,rho_dry_theta(ncells,nlev) ! dry density on theta levels (kg/m3) -real(kind=real_umphys), intent(in) :: exner_rho_levels(np_field,nlev) +real(kind=real_umphys), intent(in) :: exner_rho_levels(ncells,nlev) !Exner on rho levels -real(kind=real_umphys), intent(in) :: exner_layer_centres(np_field,0:nlev) +real(kind=real_umphys), intent(in) :: exner_layer_centres(ncells,0:nlev) !Exner -real(kind=real_umphys), intent(in) :: exner_layer_boundaries(np_field,0:nlev) +real(kind=real_umphys), intent(in) :: exner_layer_boundaries(ncells,0:nlev) !Exner ! at half level above ! exner_layer_centres -real(kind=real_umphys), intent(in) :: pstar(npnts) ! Surface pressure (Pa) +real(kind=real_umphys), intent(in) :: pstar(seg_size) ! Surface pressure (Pa) -real(kind=real_umphys), intent(in) :: p_layer_centres(np_field,0:nlev) +real(kind=real_umphys), intent(in) :: p_layer_centres(ncells,0:nlev) !Pressure(Pa) -real(kind=real_umphys), intent(in) :: p_layer_boundaries(np_field,0:nlev) +real(kind=real_umphys), intent(in) :: p_layer_boundaries(ncells,0:nlev) ! Pressure ! at half level above ! p_layer_centres (Pa) -real(kind=real_umphys), intent(in) :: z_theta(np_field,nlev) ! height of theta +real(kind=real_umphys), intent(in) :: z_theta(ncells,nlev) ! height of theta ! levels above surface (m) -real(kind=real_umphys), intent(in) :: z_rho(np_field,nlev) +real(kind=real_umphys), intent(in) :: z_rho(ncells,nlev) ! height of rho levels ! above surface (m) -real(kind=real_umphys), intent(in) :: t1_sd(npnts) ! Standard deviation of +real(kind=real_umphys), intent(in) :: t1_sd(seg_size) ! Standard deviation of ! turbulent fluctuations of ! layer 1 temp. (K) -real(kind=real_umphys), intent(in) :: q1_sd(npnts) ! Standard deviation of +real(kind=real_umphys), intent(in) :: q1_sd(seg_size) ! Standard deviation of ! turbulent fluctuations of ! layer 1 q (kg/kg) -real(kind=real_umphys), intent(in) :: th(np_field,nlev) !Model potential +real(kind=real_umphys), intent(in) :: th(ncells,nlev) !Model potential ! temperature (K) -real(kind=real_umphys), intent(in) :: q(np_field,nlev) +real(kind=real_umphys), intent(in) :: q(ncells,nlev) ! Model water vapour (kg/kg) real(kind=real_umphys), intent(in) :: timestep ! Model timestep (s) -real(kind=real_umphys), intent(in) :: q_wtrac(np_field,nlev,n_wtrac) +real(kind=real_umphys), intent(in) :: q_wtrac(ncells,nlev,n_wtrac) ! Water tracer vapour (kg/kg) -real(kind=real_umphys), intent(in) :: qcl_wtrac(np_field,nlev,n_wtrac) +real(kind=real_umphys), intent(in) :: qcl_wtrac(ncells,nlev,n_wtrac) ! Water tracer liquid ! condensate (kg/kg) -real(kind=real_umphys), intent(in) :: qcf_wtrac(np_field,nlev,n_wtrac) +real(kind=real_umphys), intent(in) :: qcf_wtrac(ncells,nlev,n_wtrac) ! Water tracer ice ! condensate (kg/kg) -real(kind=real_umphys), intent(in) :: uw0(npnts) +real(kind=real_umphys), intent(in) :: uw0(seg_size) ! U-comp of surface stress(N/m2) -real(kind=real_umphys), intent(in) :: vw0(npnts) +real(kind=real_umphys), intent(in) :: vw0(seg_size) ! V-comp of surface stress(N/m2) -real(kind=real_umphys), intent(in) :: w_max(npnts) ! max w in column +real(kind=real_umphys), intent(in) :: w_max(seg_size) ! max w in column -real(kind=real_umphys), intent(in) :: u(np_field,nlev) !Model U field (m/s) +real(kind=real_umphys), intent(in) :: u(ncells,nlev) !Model U field (m/s) -real(kind=real_umphys), intent(in) :: v(np_field,nlev) !Model V field (m/s) +real(kind=real_umphys), intent(in) :: v(ncells,nlev) !Model V field (m/s) -real(kind=real_umphys), intent(in) :: w(np_field,nlev) !Model W field (m/s) +real(kind=real_umphys), intent(in) :: w(ncells,nlev) !Model W field (m/s) -real(kind=real_umphys), intent(in) :: wstar(npnts) ! Convective velocity scale +real(kind=real_umphys), intent(in) :: wstar(seg_size) ! Convective velocity scale ! (m/s) -real(kind=real_umphys), intent(in) :: wthvs(npnts) +real(kind=real_umphys), intent(in) :: wthvs(seg_size) ! Surface flux of THV (Pa m/s2) -real(kind=real_umphys), intent(in) :: zlcl(npnts) +real(kind=real_umphys), intent(in) :: zlcl(seg_size) ! Lifting condensation level accurate ! height (m) not a model level. -real(kind=real_umphys), intent(in) :: zlcl_uv(npnts) +real(kind=real_umphys), intent(in) :: zlcl_uv(seg_size) ! Lifting condensation level ! defined for the uv grid (m) -real(kind=real_umphys), intent(in) :: tnuc_new(np_field,nlev) +real(kind=real_umphys), intent(in) :: tnuc_new(ncells,nlev) ! 3D ice nucleation temperature ! as function of dust -real(kind=real_umphys), intent(in) :: tnuc_nlcl(npnts) +real(kind=real_umphys), intent(in) :: tnuc_nlcl(seg_size) !nucleation temperature as function !of dust indexed using nlcl -real(kind=real_umphys), intent(in) :: ztop_uv(npnts) ! Top of cloud layer +real(kind=real_umphys), intent(in) :: ztop_uv(seg_size) ! Top of cloud layer ! defined for the uv ! grid (m) real(kind=real_umphys), intent(in) :: & - entrain_coef(npnts) ! entrainment coefficients + entrain_coef(seg_size) ! entrainment coefficients real(kind=real_umphys), intent(in) :: & - g_ccp(npnts) & ! cold-pool reduced gravity - ,h_ccp(npnts) & ! cold-pool depth - ,ccp_strength(npnts) ! cold-pool strength + g_ccp(seg_size) & ! cold-pool reduced gravity + ,h_ccp(seg_size) & ! cold-pool depth + ,ccp_strength(seg_size) ! cold-pool strength -real(kind=real_umphys), intent(in) :: conv_prog_precip(np_field,nlev) +real(kind=real_umphys), intent(in) :: conv_prog_precip(ncells,nlev) ! Surface precipitation ! based 3d convective ! prognostic in kg/m2/s -real(kind=real_umphys), intent(in out) :: conv_prog_flx(np_field,nlev) +real(kind=real_umphys), intent(in out) :: conv_prog_flx(ncells,nlev) ! Mass flux convective ! prognostic in Pa/s ! History prognostics only in use if l_conv_hist = .true. real(kind=real_umphys), intent(in out) :: & - deep_flag(npnts) & ! 0.0-1.0, 1. indicates deep last time step - ,past_conv_ht(npnts) ! convective height (m) + deep_flag(seg_size) & ! 0.0-1.0, 1. indicates deep last time step + ,past_conv_ht(seg_size) ! convective height (m) logical, intent(in) :: l_tracer ! Switch for inclusion of tracers -logical, intent(in) :: l_shallow_bl(npnts) ! Shallow cumulus +logical, intent(in) :: l_shallow_bl(seg_size) ! Shallow cumulus ! indicator -logical, intent(in) :: l_congestus(npnts) ! congestus cumulus +logical, intent(in) :: l_congestus(seg_size) ! congestus cumulus -logical, intent(in) :: l_mid(npnts) ! possible mid-level cnv +logical, intent(in) :: l_mid(seg_size) ! possible mid-level cnv -logical, intent(in) :: cumulus_bl(npnts) ! Cumulus indicator +logical, intent(in) :: cumulus_bl(seg_size) ! Cumulus indicator logical, intent(in) :: l_calc_dxek ! Switch for calculation of ! condensate increment @@ -361,7 +361,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! parcel variables when ! calculating condensate incr. -logical, intent(in) :: bland(npnts) ! Land/sea mask +logical, intent(in) :: bland(seg_size) ! Land/sea mask ! ! Arguments with intent INOUT: @@ -371,163 +371,163 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! specific humidities if l_mr_physics = .false. ! mixing ratios if l_mr_physics = .true. -real(kind=real_umphys), intent(in out) :: qcl(np_field,nlev) +real(kind=real_umphys), intent(in out) :: qcl(ncells,nlev) ! Liq condensate (kg/kg) -real(kind=real_umphys), intent(in out) :: qcf(np_field,nlev) +real(kind=real_umphys), intent(in out) :: qcf(ncells,nlev) ! Ice condensate (kg/kg) -real(kind=real_umphys), intent(in out) :: cf_liquid(np_field,nlev) +real(kind=real_umphys), intent(in out) :: cf_liquid(ncells,nlev) ! Liq water cloud volume (fraction) -real(kind=real_umphys), intent(in out) :: cf_frozen(np_field,nlev) +real(kind=real_umphys), intent(in out) :: cf_frozen(ncells,nlev) ! Frozen water cloud volume (fraction?) -real(kind=real_umphys), intent(in out) :: bulk_cf(np_field,nlev) +real(kind=real_umphys), intent(in out) :: bulk_cf(ncells,nlev) ! Bulk total cloud ! volume ( ) -real(kind=real_umphys), intent(in out) :: tracer(np_field,trlev,ntra) +real(kind=real_umphys), intent(in out) :: tracer(ncells,trlev,ntra) !Model tracer ! fields (kg/kg) real(kind=real_umphys), intent(in out) :: & - w2p(np_field,nlev) ! (Parcel vertical velocity)^2 [(m/s)^2] + w2p(ncells,nlev) ! (Parcel vertical velocity)^2 [(m/s)^2] ! ! Arguments with intent out: ! -real(kind=real_umphys), intent(out) :: dqclbydt(np_field,nlev) +real(kind=real_umphys), intent(out) :: dqclbydt(ncells,nlev) ! Increments to liq ! condensate due to convection ! (kg/kg/s) -real(kind=real_umphys), intent(out) :: dqcfbydt(np_field,nlev) +real(kind=real_umphys), intent(out) :: dqcfbydt(ncells,nlev) ! Increments to ice ! condensate due to convection ! (kg/kg/s) -real(kind=real_umphys), intent(out) :: dcflbydt(np_field,nlev) +real(kind=real_umphys), intent(out) :: dcflbydt(ncells,nlev) ! Increments to liq ! cloud volume due to convection ! (/s) -real(kind=real_umphys), intent(out) :: dcffbydt(np_field,nlev) +real(kind=real_umphys), intent(out) :: dcffbydt(ncells,nlev) ! Increments to ice ! cloud volume due to convection ! (/s) -real(kind=real_umphys), intent(out) :: dbcfbydt(np_field,nlev) ! Increments to +real(kind=real_umphys), intent(out) :: dbcfbydt(ncells,nlev) ! Increments to ! total cld volume due to ! convection(/s) -real(kind=real_umphys), intent(out) :: dthbydt(np_field,nlev) ! Increments to +real(kind=real_umphys), intent(out) :: dthbydt(ncells,nlev) ! Increments to ! potential temp. due to convection (K/s) -real(kind=real_umphys), intent(out) :: dqbydt(np_field,nlev) +real(kind=real_umphys), intent(out) :: dqbydt(ncells,nlev) ! Increments to q due ! to convection (kg/kg/s) -real(kind=real_umphys), intent(out) :: dubydt(np_field,nlev+1) +real(kind=real_umphys), intent(out) :: dubydt(ncells,nlev+1) ! Increments to U due ! to CMT (m/s2) -real(kind=real_umphys), intent(out) :: dvbydt(np_field,nlev+1) +real(kind=real_umphys), intent(out) :: dvbydt(ncells,nlev+1) ! Increments to V due ! to CMT (m/s2) -real(kind=real_umphys), intent(out) :: dqbydt_wtrac(np_field,nlev,n_wtrac) +real(kind=real_umphys), intent(out) :: dqbydt_wtrac(ncells,nlev,n_wtrac) ! Increments to q_wtrac due ! to convection (kg/kg/s) -real(kind=real_umphys), intent(out) :: dqclbydt_wtrac(np_field,nlev,n_wtrac) +real(kind=real_umphys), intent(out) :: dqclbydt_wtrac(ncells,nlev,n_wtrac) ! Increments to qcl_wtrac ! due to convection (kg/kg/s) -real(kind=real_umphys), intent(out) :: dqcfbydt_wtrac(np_field,nlev,n_wtrac) +real(kind=real_umphys), intent(out) :: dqcfbydt_wtrac(ncells,nlev,n_wtrac) ! Increments to qcf_wtrac ! due to convection (kg/kg/s) -real(kind=real_umphys), intent(out) :: rain(npnts) ! Surface convective rainfall +real(kind=real_umphys), intent(out) :: rain(seg_size) ! Surface convective rainfall ! (kg/m2/s) -real(kind=real_umphys), intent(out) :: snow(npnts) ! Surface convective snowfall +real(kind=real_umphys), intent(out) :: snow(seg_size) ! Surface convective snowfall ! (kg/m2/s) -real(kind=real_umphys), intent(in out) :: rain_3d(np_field,nlev) +real(kind=real_umphys), intent(in out) :: rain_3d(ncells,nlev) ! convective rainfall flux ! (kg/m2/s) -real(kind=real_umphys), intent(in out) :: snow_3d(np_field,nlev) +real(kind=real_umphys), intent(in out) :: snow_3d(ncells,nlev) ! convective snowfall flux ! (kg/m2/s) -real(kind=real_umphys), intent(out) :: rain_wtrac(np_field,n_wtrac) +real(kind=real_umphys), intent(out) :: rain_wtrac(ncells,n_wtrac) ! Surface convective water ! tracer rainfall (kg/m2/s) -real(kind=real_umphys), intent(out) :: snow_wtrac(np_field,n_wtrac) +real(kind=real_umphys), intent(out) :: snow_wtrac(ncells,n_wtrac) ! Surface convective water ! tracer snowfall (kg/m2/s) ! Section 5 Convective Cloud properties real(kind=real_umphys), intent(out) :: & - cca(np_field,n_cca_lev) &! Cnv. cld amount (0-1) -, ccw(np_field,nlev) &! Cnv. in-cld liquid water (kg/kg) -, cclwp(npnts) &! Condensed water path (kg/m^2) -, lcca(npnts) ! Lowest cnv. cld amt. (0-1) + cca(ncells,n_cca_lev) &! Cnv. cld amount (0-1) +, ccw(ncells,nlev) &! Cnv. in-cld liquid water (kg/kg) +, cclwp(seg_size) &! Condensed water path (kg/m^2) +, lcca(seg_size) ! Lowest cnv. cld amt. (0-1) integer, intent(out) :: & - iccb(npnts) &! Cnv. cld base level -, icct(npnts) &! Cnv. cld top level -, lcbase(npnts) &! Lowest cnv. cld base level -, lctop(npnts) ! Lowest cnv. cld top level + iccb(seg_size) &! Cnv. cld base level +, icct(seg_size) &! Cnv. cld top level +, lcbase(seg_size) &! Lowest cnv. cld base level +, lctop(seg_size) ! Lowest cnv. cld top level ! Section 0 Convective Cloud properties for Radiative impacts real(kind=real_umphys) :: & - cca0(np_field,n_cca_lev) &! Cnv. cld amount (0-1) -, cca0_sh(np_field,n_cca_lev) &! Shallow cnv. cld amount (0-1) -, cca0_md(np_field,n_cca_lev) &! Mid-level cnv. cld amount (0-1) -, cca0_dp(np_field,n_cca_lev) &! Deep cnv. cld amount (0-1) -, ccw0(np_field,nlev) &! Cnv. in-cld liquid water (kg/kg) -, cclwp0(npnts) ! Cond. water path (kg/m^2) + cca0(ncells,n_cca_lev) &! Cnv. cld amount (0-1) +, cca0_sh(ncells,n_cca_lev) &! Shallow cnv. cld amount (0-1) +, cca0_md(ncells,n_cca_lev) &! Mid-level cnv. cld amount (0-1) +, cca0_dp(ncells,n_cca_lev) &! Deep cnv. cld amount (0-1) +, ccw0(ncells,nlev) &! Cnv. in-cld liquid water (kg/kg) +, cclwp0(seg_size) ! Cond. water path (kg/m^2) integer, intent(out) :: & - iccb0(npnts) &! Cnv. cld base level -, icct0(npnts) &! Cnv. cld top level -, lcbase0(npnts) ! Lowest cnv. cld base level + iccb0(seg_size) &! Cnv. cld base level +, icct0(seg_size) &! Cnv. cld top level +, lcbase0(seg_size) ! Lowest cnv. cld base level -integer, intent(out) :: freeze_lev(npnts) !index for freezing lev +integer, intent(out) :: freeze_lev(seg_size) !index for freezing lev -integer, intent(out) :: kterm_deep(npnts) ! index deep conv -integer, intent(out) :: kterm_shall(npnts) ! level for shallow termination +integer, intent(out) :: kterm_deep(seg_size) ! index deep conv +integer, intent(out) :: kterm_shall(seg_size) ! level for shallow termination -logical, intent(out) :: l_mid_all(npnts) ! on exit true if mid level +logical, intent(out) :: l_mid_all(seg_size) ! on exit true if mid level ! convection has triggered real(kind=real_umphys), intent(out) :: & - deep_cfl_limited(npnts) & ! indicator for cfl limited deep conv - ,mid_cfl_limited(npnts) ! indicator for cfl limited mid conv + deep_cfl_limited(seg_size) & ! indicator for cfl limited deep conv + ,mid_cfl_limited(seg_size) ! indicator for cfl limited mid conv -real(kind=real_umphys), intent(out) :: precip_deep(npnts) +real(kind=real_umphys), intent(out) :: precip_deep(seg_size) ! deep precip (kg/m2/s) -real(kind=real_umphys), intent(out) :: precip_shall(npnts) +real(kind=real_umphys), intent(out) :: precip_shall(seg_size) ! shallow precip(kg/m2/s) -real(kind=real_umphys), intent(out) :: precip_mid(npnts) ! mid precip (kg/m2/s) -real(kind=real_umphys), intent(out) :: precip_cong(npnts) +real(kind=real_umphys), intent(out) :: precip_mid(seg_size) ! mid precip (kg/m2/s) +real(kind=real_umphys), intent(out) :: precip_cong(seg_size) ! congest precip (kg/m2/s) real(kind=real_umphys), intent(out) :: & - wstar_dn(npnts) & ! subcloud layer convective velocity scale(m/s) - , wstar_up(npnts) & ! cumulus layer convective velocity scale (m/s) - , mb1(npnts) & ! cloud base mass flux from wstar_dn (m/s) - , mb2(npnts) ! cloud base mass flux for cloud layer (m/s) + wstar_dn(seg_size) & ! subcloud layer convective velocity scale(m/s) + , wstar_up(seg_size) & ! cumulus layer convective velocity scale (m/s) + , mb1(seg_size) & ! cloud base mass flux from wstar_dn (m/s) + , mb2(seg_size) ! cloud base mass flux for cloud layer (m/s) -integer, intent(out) :: kterm_congest(npnts) ! termination level +integer, intent(out) :: kterm_congest(seg_size) ! termination level ! for congestus @@ -536,9 +536,9 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Plume model - updraught mass flux (Pa/s) ! turbulence model - mass flux (not exactly updraught) (m/s) -real(kind=real_umphys), intent(out) :: up_flux(np_field,nlev) ! mass flux +real(kind=real_umphys), intent(out) :: up_flux(ncells,nlev) ! mass flux -real(kind=real_umphys), intent(out) :: up_flux_half(np_field,nlev) +real(kind=real_umphys), intent(out) :: up_flux_half(ncells,nlev) !mass flux on rho !dummy variable not used in turbulence @@ -546,32 +546,32 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Diagnostics with no meaning for turbulence based schemes ! real(kind=real_umphys), intent(out) :: & - dwn_flux(np_field,nlev) & ! Downdraught mass flux (Pa/s) + dwn_flux(ncells,nlev) & ! Downdraught mass flux (Pa/s) - ,entrain_up(np_field,nlev) & ! Fractional entrainment rate into + ,entrain_up(ncells,nlev) & ! Fractional entrainment rate into ! updraughts (Pa/s) - ,detrain_up(np_field,nlev) & ! Fractional detrainment rate into + ,detrain_up(ncells,nlev) & ! Fractional detrainment rate into ! updraughts (Pa/s) - ,entrain_dwn(np_field,nlev) & ! Fractional entrainment rate into + ,entrain_dwn(ncells,nlev) & ! Fractional entrainment rate into ! downdraughts (Pa/s) - ,detrain_dwn(np_field,nlev) ! Fractional detrainment rate into + ,detrain_dwn(ncells,nlev) ! Fractional detrainment rate into ! downdraughts (Pa/s) ! ! Diagnostics relating to momentum fluxes ! real(kind=real_umphys), intent(out) :: & - uw_deep(np_field,nlev) & ! X-comp. of stress from deep convection + uw_deep(ncells,nlev) & ! X-comp. of stress from deep convection !(kg/m/s2) - , vw_deep(np_field,nlev) & ! Y-comp. of stress from deep convection + , vw_deep(ncells,nlev) & ! Y-comp. of stress from deep convection !(kg/m/s2) - , uw_shall(np_field,nlev) & ! X-comp. of stress from shallow + , uw_shall(ncells,nlev) & ! X-comp. of stress from shallow ! convection (kg/m/s2) - , vw_shall(np_field,nlev) & ! Y-comp. of stress from shallow + , vw_shall(ncells,nlev) & ! Y-comp. of stress from shallow ! convection (kg/m/s2) - , uw_mid(np_field,nlev) & ! U comp of stress from mid convection (kg/m/s2) - , vw_mid(np_field,nlev) ! V comp of stress from mid convection (kg/m/s2) + , uw_mid(ncells,nlev) & ! U comp of stress from mid convection (kg/m/s2) + , vw_mid(ncells,nlev) ! V comp of stress from mid convection (kg/m/s2) -real(kind=real_umphys), intent(out) :: cape_out(npnts) +real(kind=real_umphys), intent(out) :: cape_out(seg_size) ! Saved convective available ! potential energy for diagnostic ! output (Jkg-1) @@ -579,62 +579,62 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Fluxes from turbulence based convection schemes real(kind=real_umphys), intent(out) :: & - wqt_flux_sh(np_field,nlev) & ! w'qt' flux (m/s kg/kg) - , wthetal_flux_sh(np_field,nlev) & ! w'thetal' flux (m/s K) - , wthetav_flux_sh(np_field,nlev) & ! w'thetav' flux (m/s K) - , wql_flux_sh(np_field,nlev) & ! w'ql' flux (m/s kg/kg) + wqt_flux_sh(ncells,nlev) & ! w'qt' flux (m/s kg/kg) + , wthetal_flux_sh(ncells,nlev) & ! w'thetal' flux (m/s K) + , wthetav_flux_sh(ncells,nlev) & ! w'thetav' flux (m/s K) + , wql_flux_sh(ncells,nlev) & ! w'ql' flux (m/s kg/kg) - , mf_deep(np_field,nlev) & ! mass flux deep - , mf_congest(np_field,nlev) & ! mass flux congestus - , mf_shall(np_field,nlev) & ! mass flux shallow - , mf_midlev(np_field,nlev) & ! mass flux mid-lev + , mf_deep(ncells,nlev) & ! mass flux deep + , mf_congest(ncells,nlev) & ! mass flux congestus + , mf_shall(ncells,nlev) & ! mass flux shallow + , mf_midlev(ncells,nlev) & ! mass flux mid-lev - , dt_deep(np_field,nlev) & ! dt increment deep (K/s) - , dt_congest(np_field,nlev) & ! dt increment congestus (K/s) - , dt_shall(np_field,nlev) & ! dt increment shallow (K/s) - , dt_midlev(np_field,nlev) & ! dt increment mid-level (K/s) + , dt_deep(ncells,nlev) & ! dt increment deep (K/s) + , dt_congest(ncells,nlev) & ! dt increment congestus (K/s) + , dt_shall(ncells,nlev) & ! dt increment shallow (K/s) + , dt_midlev(ncells,nlev) & ! dt increment mid-level (K/s) - , dq_deep(np_field,nlev) & ! dq increment deep (kg/kg/s) - , dq_congest(np_field,nlev) & ! dq increment congestus (kg/kg/s) - , dq_shall(np_field,nlev) & ! dq increment shallow (kg/kg/s) - , dq_midlev(np_field,nlev) & ! dq increment mid-level (kg/kg/s) + , dq_deep(ncells,nlev) & ! dq increment deep (kg/kg/s) + , dq_congest(ncells,nlev) & ! dq increment congestus (kg/kg/s) + , dq_shall(ncells,nlev) & ! dq increment shallow (kg/kg/s) + , dq_midlev(ncells,nlev) & ! dq increment mid-level (kg/kg/s) - , du_deep(np_field,nlev+1) & ! du increment deep (m/s) - , du_congest(np_field,nlev+1) & ! du increment congestus (m/s) - , du_shall(np_field,nlev+1) & ! du increment shallow (m/s) - , du_midlev(np_field,nlev+1) & ! du increment mid-level (m/s) + , du_deep(ncells,nlev+1) & ! du increment deep (m/s) + , du_congest(ncells,nlev+1) & ! du increment congestus (m/s) + , du_shall(ncells,nlev+1) & ! du increment shallow (m/s) + , du_midlev(ncells,nlev+1) & ! du increment mid-level (m/s) - , dv_deep(np_field,nlev+1) & ! dv increment deep (m/s) - , dv_congest(np_field,nlev+1) & ! dv increment congestus (m/s) - , dv_shall(np_field,nlev+1) & ! dv increment shallow (m/s) - , dv_midlev(np_field,nlev+1) ! dv increment mid-level (m/s) + , dv_deep(ncells,nlev+1) & ! dv increment deep (m/s) + , dv_congest(ncells,nlev+1) & ! dv increment congestus (m/s) + , dv_shall(ncells,nlev+1) & ! dv increment shallow (m/s) + , dv_midlev(ncells,nlev+1) ! dv increment mid-level (m/s) real(kind=real_umphys), intent(out) :: & - ind_cape_reduced(npnts) & ! indicates cape timescale reduced - ,cape_ts_used(npnts) & ! cape timescale for deep (s) - ,ind_deep(npnts) & ! indicator of real deep - ,ind_shall(npnts) ! indicator of real shallow + ind_cape_reduced(seg_size) & ! indicates cape timescale reduced + ,cape_ts_used(seg_size) & ! cape timescale for deep (s) + ,ind_deep(seg_size) & ! indicator of real deep + ,ind_shall(seg_size) ! indicator of real shallow real(kind=real_umphys), intent(out) :: & - dt_dd(np_field,nlev) & ! dT/dt from DD & evap below cloud base (K/s) - ,dq_dd(np_field,nlev) & ! dq/dt from DD & evap below cloud base (kg/kg/s) - ,du_dd(np_field,nlev) & ! du/dt from DD (m/s2) - ,dv_dd(np_field,nlev) & ! dv/dt from DD (m/s2) - ,area_ud(np_field,nlev) & ! updraught fractional area - ,area_dd(np_field,nlev) ! downdraught fractional area + dt_dd(ncells,nlev) & ! dT/dt from DD & evap below cloud base (K/s) + ,dq_dd(ncells,nlev) & ! dq/dt from DD & evap below cloud base (kg/kg/s) + ,du_dd(ncells,nlev) & ! du/dt from DD (m/s2) + ,dv_dd(ncells,nlev) & ! dv/dt from DD (m/s2) + ,area_ud(ncells,nlev) & ! updraught fractional area + ,area_dd(ncells,nlev) ! downdraught fractional area ! Structure containing SCM convection sub-step diagnostics ! (needs intent inout as contains allocatable arrays that need to ! retain their allocated status on input as well as output) -type(scm_convss_dg_type), intent(in out) :: scm_convss_dg( npnts ) +type(scm_convss_dg_type), intent(in out) :: scm_convss_dg( seg_size ) ! Flag for SCM convection sub-step diagnostics logical, intent(in) :: l_scm_convss_dg ! local required in move mixing to glue -real(kind=real_umphys) :: dtrabydt(npnts,nlev,ntra) ! Increment to tracer due to +real(kind=real_umphys) :: dtrabydt(seg_size,nlev,ntra) ! Increment to tracer due to ! convection (kg/kg/s) ! Structure containing compressed water fields (used for deep, shallow and @@ -1070,7 +1070,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & !----------------------------------------------------------------------- ! LOCAL compressed arrays to be passed to MID-LEVEL convection scheme. ! Arrays are identified by underscore MD (_md) and are of length -! npnts where npnts is the total number of points in the grid (since +! seg_size where seg_size is the total number of points in the grid (since ! mid-level convection may occur on any point previously diagnosed as ! shallow or deep). !----------------------------------------------------------------------- @@ -1247,57 +1247,57 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & !----------------------------------------------------------------------- ! Arrays required for mixing ratio to specific conversions -real(kind=real_umphys) :: mt(npnts,nlev) ! total water mixing ratio (kg/kg) +real(kind=real_umphys) :: mt(seg_size,nlev) ! total water mixing ratio (kg/kg) ! rhowet/rhodry = 1 + mt real(kind=real_umphys) :: denom ! 1/denominator !----------------------------------------------------------------------- ! Arrays required by 3d CCA calculation -real(kind=real_umphys), intent(in out) :: cca_2d(npnts) +real(kind=real_umphys), intent(in out) :: cca_2d(seg_size) ! 2d convective cloud (Section 5) ! Saturation mixing ratio calulation and 1/pstar real(kind=real_umphys) :: & - qse_mix(npnts,nlev) ! Saturation mixing ratio of cloud + qse_mix(seg_size,nlev) ! Saturation mixing ratio of cloud ! cloud environment (kg/kg) only used if ! turbulence schemes in use real(kind=real_umphys) :: & - recip_pstar(npnts) & + recip_pstar(seg_size) & ! Reciprocal of pstar array - , qse(npnts,nlev) & + , qse(seg_size,nlev) & ! Saturation specific humidity of cloud ! cloud environment (kg/kg) - , pt(npnts) & + , pt(seg_size) & ! Temporary store for P in calc. of sat. ! value. (Pa) - , tt(npnts) & + , tt(seg_size) & ! Temporary store for T in calc. ! of saturation value. (K) - , ttkm1(npnts) ! Temporary store for T in layer + , ttkm1(seg_size) ! Temporary store for T in layer ! k-1 for use in freezing level ! calc. for anvil. (K) ! arrays required by grid calculations real(kind=real_umphys) :: & - r2rho_th(npnts,nlev) & ! radius**2 density theta lev (kg/m) - ,r2rho(npnts,nlev) & ! radius**2 density rho lev (kg/m) - ,dr_across_th(npnts,nlev) & ! thickness of theta levels (m) - ,dr_across_rh(npnts,nlev) ! thickness of rho levels (m) + r2rho_th(seg_size,nlev) & ! radius**2 density theta lev (kg/m) + ,r2rho(seg_size,nlev) & ! radius**2 density rho lev (kg/m) + ,dr_across_th(seg_size,nlev) & ! thickness of theta levels (m) + ,dr_across_rh(seg_size,nlev) ! thickness of rho levels (m) ! arrays required by for identifying convective points -integer :: index1(npnts) +integer :: index1(seg_size) integer :: nconv_all ! Total number of points convecting ! array required by tracers at end -real(kind=real_umphys) :: limited_step(npnts) ! Reduced step size for tracer +real(kind=real_umphys) :: limited_step(seg_size) ! Reduced step size for tracer ! mixing -real(kind=real_umphys) :: step_test(npnts) +real(kind=real_umphys) :: step_test(seg_size) ! Work array used in reducing step ! @@ -1333,7 +1333,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! ! Initialise 3d rain variables -call init_6a_rain(npnts, nlev, n_sh, n_dp, n_cg, n_md, rain_3d_sh, snow_3d_sh, & +call init_6a_rain(seg_size, nlev, n_sh, n_dp, n_cg, n_md, rain_3d_sh, snow_3d_sh, & rain_3d_dp, snow_3d_dp, rain_3d_cg, snow_3d_cg, rain_3d_md, & snow_3d_md, ind_cape_reduced, cape_ts_used, ind_deep, & ind_shall, kterm_deep, kterm_shall, kterm_congest ) @@ -1354,7 +1354,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! at all points. Points not in the compression lists for the respective calls ! to DPCONV, SHCONV, MDCONV or CGCONV will remain zero. -call init_6a_npnts(npnts, nlev, n_cca_lev, np_field, n_wtrac, & +call init_6a_npnts(seg_size, nlev, n_cca_lev, ncells, n_wtrac, & dqbydt, dthbydt, dqclbydt, dqcfbydt, dcflbydt, dcffbydt, & dbcfbydt, dqbydt_wtrac, dqclbydt_wtrac, & dqcfbydt_wtrac, ccw, cca, & @@ -1373,7 +1373,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Initialisation of mt used for mixing/specific conversions using wet/dry rho. ! Also zero dubydt, dvbydt and dtrabydt arrays. -call init_6a_moist(npnts, nlev, np_field, ntra, rho_theta, rho_dry_theta, & +call init_6a_moist(seg_size, nlev, ncells, ntra, rho_theta, rho_dry_theta, & mt, dubydt, dvbydt, dtrabydt, l_tracer) ! ! Required to get same convective cloud as old scheme @@ -1389,7 +1389,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Calculate quantities involving density etc for future use do k=1,nlev - do i=1,npnts + do i=1,seg_size dr_across_rh(i,k) = r_theta(i,k) - r_theta(i,k-1) r2rho(i,k) = r_rho(i,k)*r_rho(i,k)*rho(i,k) end do @@ -1398,13 +1398,13 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! rho_theta only set for nlev-1 ! k=1 ! bottom theta level thicker -do i=1,npnts +do i=1,seg_size dr_across_th(i,k) = r_rho(i,k+1) - r_theta(i,0) r2rho_th(i,k) = r_theta(i,k)*r_theta(i,k)*rho_theta(i,k) end do do k=2,nlev-1 - do i=1,npnts + do i=1,seg_size dr_across_th(i,k) = r_rho(i,k+1) - r_rho(i,k) r2rho_th(i,k) = r_theta(i,k)*r_theta(i,k)*rho_theta(i,k) end do @@ -1412,7 +1412,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & k=nlev ! top layer (hope not used ? ! assume density as layer below) -do i=1,npnts +do i=1,seg_size dr_across_th(i,k) = r_theta(i,nlev) - r_rho(i,k) r2rho_th(i,k) = r_theta(i,k)*r_theta(i,k)*rho_theta(i,k-1) end do @@ -1427,7 +1427,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Calculate 1/pstar and initialize freeze_lev array. ! -do i = 1,npnts +do i = 1,seg_size recip_pstar(i)=1.0 / pstar(i) freeze_lev(i) = 1 end do @@ -1443,7 +1443,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! if (k == 1) then - do i = 1,npnts + do i = 1,seg_size tt(i) = th(i,k) * exner_layer_centres(i,k) pt(i) = p_layer_centres(i,k) ! @@ -1456,7 +1456,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & end do else - do i = 1,npnts + do i = 1,seg_size ttkm1(i) = tt(i) tt(i) = th(i,k) * exner_layer_centres(i,k) pt(i) = p_layer_centres(i,k) @@ -1472,12 +1472,12 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Calculate saturation specific humidity/mixing ratio lq_mix=.false. ! - call qsat(qse(:,k),tt,pt,npnts) + call qsat(qse(:,k),tt,pt,seg_size) if (iconv_deep == 2 .or. (iconv_shallow >= 2) ) then ! Using a turbulence scheme also require a mixing ratio version - call qsat_mix(qse_mix(:,k),tt,pt,npnts) + call qsat_mix(qse_mix(:,k),tt,pt,seg_size) end if end do ! nlev @@ -1512,7 +1512,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & allocate(rho_dry_theta_temp(n_dp,nlev)) j = 0 - do i = 1,npnts + do i = 1,seg_size if (cumulus_bl(i) .and. .not. l_shallow_bl(i) .and. & .not. l_congestus(i)) then j = j+1 @@ -1681,7 +1681,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & if (l_wtrac_conv) then - call wtrac_gather_conv(np_field,npnts,n_dp,nlev,n_wtrac, iconv_deep, & + call wtrac_gather_conv(ncells,seg_size,n_dp,nlev,n_wtrac, iconv_deep, & dpi, mt, q_wtrac, qcl_wtrac, qcf_wtrac, wtrac_e) end if @@ -1998,7 +1998,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! required and decompress arrays if (l_wtrac_conv) then - call wtrac_scatter_conv(np_field, npnts, n_dp, nlev, n_wtrac, & + call wtrac_scatter_conv(ncells, seg_size, n_dp, nlev, n_wtrac, & iconv_deep, dpi, mt, wtrac_e, & dqbydt_wtrac, dqclbydt_wtrac, dqcfbydt_wtrac) end if @@ -2204,7 +2204,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & decay_amount= timestep/decay_period - do i = 1,npnts + do i = 1,seg_size l_deep=cumulus_bl(i) .and. .not. l_shallow_bl(i) .and. & .not. l_congestus(i) ! Decay flag ensuring 0.0 is the minimum allowed value. @@ -2232,7 +2232,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & allocate(rho_dry_theta_temp(n_sh,nlev)) j = 0 - do i = 1,npnts + do i = 1,seg_size if (cumulus_bl(i) .and. l_shallow_bl(i)) then j = j+1 shi(j) = i @@ -2377,7 +2377,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & call wtrac_alloc_conv_e(n_sh, nlev, n_wtrac, wtrac_e) if (l_wtrac_conv) then - call wtrac_gather_conv(np_field,npnts,n_sh,nlev,n_wtrac, iconv_shallow, & + call wtrac_gather_conv(ncells,seg_size,n_sh,nlev,n_wtrac, iconv_shallow, & shi, mt, q_wtrac, qcl_wtrac, qcf_wtrac, wtrac_e) end if @@ -2710,7 +2710,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! required and decompress arrays if (l_wtrac_conv) then - call wtrac_scatter_conv(np_field,npnts,n_sh,nlev,n_wtrac, & + call wtrac_scatter_conv(ncells,seg_size,n_sh,nlev,n_wtrac, & iconv_shallow, shi, mt, wtrac_e, & dqbydt_wtrac, dqclbydt_wtrac, dqcfbydt_wtrac) end if @@ -2906,7 +2906,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & !----------------------------------------------------------------------- j = 0 - do i = 1,npnts + do i = 1,seg_size if (cumulus_bl(i) .and. l_congestus(i)) then j = j+1 cgi(j) = i @@ -3486,7 +3486,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Create index of points where mid-level is possible ! j = 0 - do i = 1,npnts + do i = 1,seg_size if (l_mid(i)) then j = j+1 mdi(j) = i @@ -3731,7 +3731,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & call wtrac_alloc_conv_e(n_md, nlev, n_wtrac, wtrac_e) if (l_wtrac_conv) then - call wtrac_gather_conv(np_field,npnts,n_md,nlev,n_wtrac, iconv_mid, & + call wtrac_gather_conv(ncells,seg_size,n_md,nlev,n_wtrac, iconv_mid, & mdi, mt, q_wtrac, qcl_wtrac, qcf_wtrac, wtrac_e) end if @@ -4110,7 +4110,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! required and decompress arrays if (l_wtrac_conv) then - call wtrac_scatter_conv_mid(np_field,npnts,n_md,nlev,n_wtrac, & + call wtrac_scatter_conv_mid(ncells,seg_size,n_md,nlev,n_wtrac, & iconv_mid, mdi, mt, wtrac_e, & dqbydt_wtrac, dqclbydt_wtrac, dqcfbydt_wtrac) end if @@ -4255,7 +4255,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & !----------------------------------------------------------------------- nconv_all=0 -do i = 1,npnts +do i = 1,seg_size if (cumulus_bl(i) .or. l_mid_all(i)) then nconv_all = nconv_all + 1 index1(nconv_all) = i @@ -4318,7 +4318,7 @@ subroutine glue_conv_6a(np_field,npnts,nlev,n_wtrac,nbl, & ! Added as something wrong with top level CCA ! zeroing cca -do i=1,npnts +do i=1,seg_size cca(i,n_cca_lev) = 0.0 cca0(i,n_cca_lev) = 0.0 end do